Datomic - требует явного ручного кодирования уникальных идентификаторов?

Мой вопрос: действительно ли Dataomic требует явного ручного создания уникальных порядковых номеров конечным пользователем? Или это только пример?

Я читаю учебник Datomic.

Когда я просматриваю данные, загружаемые в файл seattle-data0.dtm, я вижу в первых двух строках:

[
{:district/region :region/e, :db/id #db/id[:db.part/user -1000001], :district/name "East"}
{:db/id #db/id[:db.part/user -1000002], :neighborhood/name "Capitol Hill", :neighborhood/district #db/id[:db.part/user -1000001]}

Обратите внимание, в частности, на значения

:db/id #db/id[:db.part/user -1000001],
:db/id #db/id[:db.part/user -1000002]
#db/id[:db.part/user -1000001]

Возможно, вы можете помочь мне понять - при подготовке данных для вставки явно требуется уникальный уникальный порядковый номер ID.

Разумеется, в современной базе данных мы можем полагаться на базу данных для создания порядковых номеров для нас?

Когда я иду, чтобы сделать свою собственную схему примера и вставить данные, я обнаружил, что мне также необходимо ввести идентификационные номера вручную. Что мне не хватает?

Ответ 1

Чтобы ответить на ваш вопрос: No Datomic не требует, чтобы конечный пользователь генерировал идентификаторы. То, что вы видите в примере Сиэтла, временные идентификаторы.

Каждый раз, когда вы хотите добавить некоторые факты о новых объектах в Datomic, вы должны предоставить каждому новому объекту временный идентификатор. Этот идентификатор будет заменен реальным уникальным идентификатором Datomic.

Теперь вы можете спросить себя, почему вам нужно использовать эти временные идентификаторы в первую очередь? Временные идентификаторы необходимы для выражения отношений между всеми новыми объектами в одной транзакции. В вашем примере у вас есть идентификаторы:

:db/id #db/id[:db.part/user -1000001],
:db/id #db/id[:db.part/user -1000002]
#db/id[:db.part/user -1000001]

два из них одинаковы (я объясню отрицательные числа в один момент). Это означает, что новый объект, помеченный временным идентификатором #db/id[:db.part/user -1000001], одинаковый в утверждения.

Теперь я должен объяснить литерал данных (другая ссылка) #db/id[:db.part/user -1000001]. #db/id - это тег для временного идентификатора Datomic. За тегом следует вектор двух компонентов :db.part/user и -1000001. Первая часть - раздел базы данных и является обязательной. Вторая часть является необязательной. Если вы пишете только #db/id[:db.part/user], каждый раз, когда происходит этот литерал, вы получаете новый (другой) временный идентификатор. Если вы пишете #db/id[:db.part/user -1000001], вы получаете одинаковый временный идентификатор каждый раз, когда используете отрицательный индекс -1000001. Итак, #db/id[:db.part/user -1000001] отличается от #db/id[:db.part/user -1000002].

Я точно не знаю, почему примеры используют индексы ниже 1000000. JavaDoc tempid, где литерал данных #db/id разрешает, говорит, что числа от -1 (включительно) до -1000000 (эксклюзивные) зарезервированы для созданных пользователем temp ids. Так что, возможно, кто-то может пролить свет на это.

Подводя итог: #db/id[...] являются временными идентификаторами для выражения одинаковых объектов в одной транзакции и заменяются реальными уникальными идентификаторами Datomic в конце транзакции. Если вам не нужно ссылаться на один и тот же объект в транзакции дважды, вы можете просто #db/id[:db.part/user] для каждого временного идентификатора.