我正在寻找关于在Datomic中建模某些多对关系的方法的反馈.
假设我想为一个人有一个最喜欢的电影列表的域设计Datomic模式.举例来说,John最喜欢的电影是Gladiator,Star Wars和Fight Club.
在Datomic中对此进行建模的最明显的架构是具有基数多属性,例如:
#{["John" :person/favorite-movies "Gladiator"]
["John" :person/favorite-movies "Star Wars"]
["John" :person/favorite-movies "Fight Club"]}
Run Code Online (Sandbox Code Playgroud)
这种方法可以很容易地从列表中添加或删除电影(简单地使用:db/add和:db/retract),但我发现重置整个电影列表是不切实际的- 你基本上需要计算旧列表和新列表之间的差异,并且在事务函数中运行.当列表的元素不是标量时,这会变得更糟.
作为替代方法,我正在考虑使用set实体引入间接:
#{["John" :person/favorite-movies 42]
[42 :set.string/contains "Gladiator"]
[42 :set.string/contains "Star Wars"]
[42 :set.string/contains "Fight Club"]}
Run Code Online (Sandbox Code Playgroud)
使用这种方法,:person/favorite-movies是一个基数 - 一,ref-typed属性,并且:set.string/contains是基数多,字符串类型的属性.然后重置列表只需创建一个新的集合实体:
[{:db/id "John"
:person/favorite-movies {:db/id (d/tempid :db.part/user)
:set.string/contains ["Gladiator"
"The Lord of the Rings"
"A Clockwork Orange"
"True Romance"]}}]
Run Code Online (Sandbox Code Playgroud)
这种建模到多种关系的方法是否存在已知的局限性?