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

Ert*_*tin 1 clojure datomic datascript

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

它产生了一些long价值,不UUID Stringlong是64位,它让我想想的独特性后,某些时候,我可能会达到长的限制.反而会更难UUID.

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

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

cam*_*dez 8

顾名思义,tempid只提供临时标识; 这些将在单个事务的上下文中使用.因此,除非您在单个事务中超过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]]))
Run Code Online (Sandbox Code Playgroud)

...只能使用某种共享标识符,但在我们从数据库中往返之前,我们不知道永久插入ID.

Tempids还允许我们transact通过查看临时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))
Run Code Online (Sandbox Code Playgroud)

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

@(d/transact
   conn
   [[:db/add "beykoz" :city/district "BEYKOZ"]
    [:db/add "beykoz" :city/population 220364]])
Run Code Online (Sandbox Code Playgroud)

  • 这是很多地区!如果您有2 ^ 64个唯一:城市/区域,您的总数据集很可能是[zettabyte-sized](https://en.wikipedia.org/wiki/Zetta-),它可能是地球上最大的单个数据集,和[地球上所有数据]的重要部分(http://www.computerweekly.com/news/2240217788/Data-set-to-grow-10-fold-by-2020-as-internet-of-things -起飞).这不适合Datomic.无论您选择哪种数据库,请务必密切关注[存储成本](http://gizmodo.com/5557676/how-much-money-would-a-yottabyte-hard-drive-cost). (3认同)