Datomic 的 tempid 是否提供唯一的实体 ID?

Does Datomic's tempid provide unique entity id?

我对 datomic.api/tempid 提供实体 ID 的 fn 有一些疑问。

它产生一些 long 值,而不是 UUID String 并且 long 是 64 位的,这让我想到它的唯一性,在某些时候我可能会达到 long 的极限。使用 UUID 会更难。

当我写这样的代码时,我问自己"Does this reach the entity id limit and cause a problem when adding new entities?"

@(d/transact
   conn
   [{:db/id   (d/tempid :db.part/user)
     :city/district "BEYKOZ"}])

顾名思义,tempid只提供一个temporary标识符;这些将在单个事务的上下文中使用。所以你不会 运行 出 ID,除非你在单个交易中 超过 2^64 条新记录 ——而且这种交易对 运行 无论如何。

tempids 的主要目的是允许我们在事务中的多个位置引用新创建的实体。

事实上,基于地图的交易格式是基于矢量的格式的shorthand;如果我们想创建一个具有几个属性的城市,在内部,Datomic 正在做的事情更像是:

@(d/transact
   conn
   (let [city-id (d/tempid :db.part/user)]
     [[:db/add city-id :city/district "BEYKOZ"]
      [:db/add city-id :city/population 220364]]))

...只有使用某种共享标识符才有可能,但我们不知道永久的插入 ID,直到我们从数据库中往返。

Tempids 还允许我们通过 transact 的 return 值找到这些永久 ID,方法是查看临时 ID 到永久 ID 的映射。例如

(let [tempid (d/tempid :db.part/user)
      tx     [{:db/id tempid, :city/district "BEYKOZ"}]
      result @(d/transact conn tx)]
  (d/resolve-tempid (:db-after result) (:tempids result) tempid))

同样值得注意的是,从 Datomic 0.9.5530 开始,您不需要手动为新记录添加 tempids(只需将 :db/id 留在地图之外),您也可以使用字符串作为临时工。因此,例如,我们可以将城市交易重写为:

@(d/transact
   conn
   [[:db/add "beykoz" :city/district "BEYKOZ"]
    [:db/add "beykoz" :city/population 220364]])