clojure - 对于此模式,在 Datomic 领域中更惯用的选项是什么?

标签 clojure datomic

我有一个关于 Datomic 更惯用的模式的问题。

假设我们有实体 User , PostTopic .
Post可以属于Topic , User和其他 Post (回复)。现在,我应该,

a) 创建一个 :posts属性,这只是 Post 的列表s,并将其注入(inject)到每个需要引用 Post 的实体中年代?

或者

b) 建立更明确的关系,例如 Post有一个 :post/author属性是对用户的引用,也许是 :post/belongs-to可以引用 Topic 的属性或其他Post ?

观察:
如果我这样做 b ,我似乎得到了更多的语义关系。例如,我可以做 (:post/_author user-entity) ,这比 (:posts user-entity) 更能描述他们的关系的性质(因为,User 具有 :posts 是什么意思?是那些 User 的收藏 Post s,创作的 Post s,还是什么?)

的另一个副作用| b 是我可以创建一个新的Post不改变任何其他实体。如果我这样做 一个 ,我需要创建 Post并将其插入 :posts User 的属性,需要两个操作而不是一个。

但是,我有一种感觉,一个 可能是更惯用的方式。例如,似乎更容易看到属性列表 :posts如果User 随着时间的推移发生了变化,我应该这样做吗?引用资料 :posts而不是 Post引用 User通过:post/author属性。

什么会更可取,为什么?

最佳答案

您的选项( b )本质上是惯用的,也是进入 datomic 的唯一方法。

所有 datomic 模式仅被编码为属性可以在实体-属性-值 datom (EAV) 的结构中采用的值。

http://docs.datomic.com/schema.html - 从文档中提取的一个关键命题是:

Each Datomic database has a schema that describes the set of attributes that can be associated with entities. A schema only defines the characteristics of the attributes themselves. It does not define which attributes can be associated with which entities.



实体本身是高度抽象的(内部只是数字),实体的所有有趣属性都被编码为属性值断言。实体未键入!您可以通过为实体声明的属性创建实体的语义,例如:user/firstname、:post/title、:post/content、:topic/description 等。
这就是为什么你真的想要命名属性的原因。

一个特例是属性类型 :db.type/ref其中 EAV 中“V”的值本身就是另一个实体。这就是在实体之间创建语义关联的原因。您给每个属性一个“名称”(作为 :db/ident )来捕获 E<->E 连接的实际含义。所以你可以有一个属性 :db.type/ref:db/ident “:发布/作者”。

请注意,所有 :db.type/ref属性本质上是双向的,所以如果 Eu是代表用户的实体,Ep是表示帖子的实体,那么以下在 datom 创建和查询中是等效的:
[Ep :post/author  Eu]
[Eu :post/_author Ep]

所有实体关系只是更多的属性断言是非常灵活的。如果您以后想添加收藏帖子的概念,它只是 :db.type/ref 的另一个属性。 .使用 :db/ident 创建它例如 ":user/favorites"并断言预先存在的用户和帖子(具有不同的用户实体作为作者)之间的连接。
[aUser :user/favorites somePost]

没有集合值属性的概念,因此您在 ( a ) 中建议的内容在 datomic 中无法正确表达。您将使用查询来聚合帖子。删除后将通过实体本身的撤回来建模。此类撤回的帖子将在数据库历史记录中保持可见。

这确实带来了如何为实体列表指定顺序的挑战。您要么需要使用“自然”排序,例如帖子的日期(在 datomic 事务中捕获或作为帖子的显式属性捕获),要么使用基于属性值的显式排序,例如通过 :post/up-投票数字属性。

如果您需要实体的语义分组,其中“子实体”仅有意义并且仅作为更大事物的一部分存在 - 例如订单中的订单项实体 - 然后查看 datomic components .

关于clojure - 对于此模式,在 Datomic 领域中更惯用的选项是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20068835/

相关文章:

clojure - 为测试环境清除数据数据库?

clojure - xml/解析: how to convert the string in file into lower case before parse?

scalability - 数据原子和写入可扩展性

clojure - 在 Light Table 中使用 Datomic 时出现 "No reader function"错误

concurrency - 在Clojure中并行处理CSV文件

search - Datomic - 选择某些属性最高的实体

database - 我应该什么时候使用 Datomic?

clojure - clojure a 与非标准迭代 java API 的互操作

clojure - Clojure 如何 ^ :const work?

clojure - 莱宁根2交互模式