我对提供实体ID的datomic.api/tempid
fn有些怀疑。
它产生一些long
值,而不是UUID String
而long
是64位,这让我想到它的独特性,在某些时候我可能会达到很长的限制。用UUID
代替它会更难。
当我写这样的代码时,我会问自己“这是否达到实体ID限制并在添加新实体时导致问题?”
@(d/transact
conn
[{:db/id (d/tempid :db.part/user)
:city/district "BEYKOZ"}])
答案 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]])