Короткий инкрементный идентификатор uinque для neo4j - PullRequest
0 голосов
/ 25 июня 2018

Я использую django с neo4j в качестве базы данных.Мне нужно использовать короткий URL-адрес на основе идентификаторов узлов в моем API отдыха.В neo4j есть идентификатор, используемый в базе данных, который не рекомендовал использовать в приложении, и есть подход к использованию uuid, который слишком длинный для моих коротких URL-адресов.Поэтому я добавляю свой генератор uid:

def uid_generator():
    last_id = db.cypher_query("MATCH (n) RETURN count(*) AS lastId")[0][0][0]
    if last_id is None:
        last_id = 0
    last_id = str(last_id)
    hash = sha256()
    hash.update(str(time.time()).encode())
    return hash.hexdigest()[0:(max(2, len(last_id)))] + str(uuid.uuid4()).replace('-', '')[0:(max(2, len(last_id)))]

У меня два вопроса. Сначала я прочитал этот вопрос в переполнении стека и все еще не уверен, что MATCH (n) RETURN count(*) AS lastId равно O(1)ссылка на это!Есть ли ссылка на этот ответ?Во-вторых, есть ли лучший подход к уникальности идентификатора и скорости?

Ответы [ 3 ]

0 голосов
/ 25 июня 2018

Ваш подход не очень хорош, потому что он основан на количестве узлов в базе данных.

Что произошло, если вы создали узел (назовите его A), а затем удалили случайный узел и затем создали новый узел (назовите его B).

A и B будут иметь одинаковые идентификаторы, и я думаю, именно поэтому вы добавили хэш в код, основанный на времени (но я едва понимаю строку:)).

С другой стороны, идентификатор Neo4j гарантирует, что у вас будет уникальный идентификатор в базе данных, но не во времени. По умолчанию Neo4j перерабатывает неиспользуемый идентификатор (идентификатор удаляется при удалении узла).

Вы можете изменить это поведение, изменив конфигурацию (см. Документ ЗДЕСЬ ): dbms.ids.reuse.types.override=RELATIONSHIP

Благодаря такой конфигурации размер вашей базы данных на жестком диске может только увеличиться, даже если вы удалите узлы.

0 голосов
/ 25 июня 2018

Во-первых, вы должны наложить уникальное ограничение на свойство id, чтобы убедиться в отсутствии коллизий, создаваемых параллельными операторами create.Это требует использования метки, но вам НУЖНО это безотказное, если вы планируете делать что-то серьезное с этими данными.Но, таким образом, вы можете использовать скользящие идентификаторы для разных ярлыков.(Все индексированные метки будут иметь таблицу подсчета. UNIQUE CONSTRAINT также создает индекс)

Во-вторых, вы должны выполнить генерацию и создание в одном и том же шифре, как этот

MATCH (n:Node) WITH count(*) AS lastId
CREATE (:Node{id:lastId})

Это сведет к минимумувремя между генерацией и фиксацией, уменьшая вероятность столкновения.(Не забудьте повторить неудачные попытки из-за уникальных нарушений)

Я не уверен, что вы делаете с хэшем, просто вы делаете это неправильно.Либо вы генерируете новый UUID на основе времени (он не требует параметров) и используете его как есть, либо вы используете инкриминирующий идентификатор.(Изменяя UUID, вы лишаете законной силы логику, гарантирующую уникальность, тем самым значительно увеличивая вероятность коллизии)

Вы также можете сохранить текущее число индексов в узле, как объяснено здесь .Не гарантируется поточная безопасность, но это не должно быть проблемой, если у вас есть уникальные ограничения и повторите попытку ограничения.Это будет более терпимым к удалению узлов.

0 голосов
/ 25 июня 2018

Почему бы не создать свой собственный идентификатор? Вы можете получить максимум вашего последнего идентификатора (назовем его RN для номера записи).

match (n) возвращает max (n.RN) как lastID

max - это одна из нескольких числовых функций в шифре.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...