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

时间:2017-03-17 14:54:09

标签: clojure datomic datascript

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

它产生一些long值,而不是UUID Stringlong是64位,这让我想到它的独特性,在某些时候我可能会达到很长的限制。用UUID代替它会更难。

当我写这样的代码时,我会问自己“这是否达到实体ID限制并在添加新实体时导致问题?”

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

1 个答案:

答案 0 :(得分:8)

顾名思义,tempid仅提供 temp orary标识符;这些将在单个事务的上下文中使用。因此,除非您在单个事务中超过2 ^ 64个新记录 ,否则您将不会用完ID,而且这种交易太大而无法运行。

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

实际上,基于地图的交易格式是基于矢量格式的简写;如果我们想在内部创建一个具有几个属性的城市,那么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。

Tempid还允许我们通过查看临时ID到永久ID的映射,通过transact的返回值找到这些永久ID。 e.g。

(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开始,您不需要手动将tempid添加到新记录中(只需将:db/id留出地图),然后你就可以了也可以使用字符串作为时间。因此,例如,我们可以将城市交易重写为:

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