Datomic在这个模式中更多的习惯选择是什么?

我有一个关于什么是Datomic的更习惯性模式的问题。

假设我们有实体UserPostTopic

Post可以属于TopicUser和其他Post (回复)。 现在,我应该,

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

要么

b)建立更明确的关系,这样一个Post有一个:post/author属性是一个用户的引用,也许是一个可以引用TopicPost :post/belongs-to属性?

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

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

不过,我有一个可能是做的更地道的方式的感觉。 例如,看起来如果User引用:posts而不是通过:post/author Post引用User ,那么User属性:posts列表如何随时间推移而更改会更容易些属性。

什么是更可取的,为什么?


您的选项( b )基本上是数据集中的惯用且唯一的方法。

所有的数据模式只是作为属性在实体属性值数据库(EAV)的结构中可以采用的值而被编码。

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

每个Datomic数据库都有一个模式,用于描述可以与实体关联的一组属性。 模式只定义了属性本身的特征。 它没有定义哪些属性可以与哪些实体相关联。

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

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

请注意,所有:db.type/ref属性本质上是双向的,因此如果Eu是表示用户的实体,而Ep是表示帖子的实体,那么以下内容在数据库创建和查询中都是等效的:

[Ep :post/author  Eu]
[Eu :post/_author Ep]

所有的实体关系只是更多的属性断言是非常灵活的。 如果您稍后想要添加最喜欢的帖子的概念,它只是另一个属性:db.type/ref 。 用一个:db/ident (如“:user / favorites”)创建它,并声明预先存在的用户和帖子(与作者具有不同的用户实体)之间的连接。

[aUser :user/favorites somePost]

没有集合值属性的概念,所以你在( a )中提出的建议在数据集中不能很好地表达。 您将使用查询来聚合帖子。 删除后将通过撤回实体本身来建模。 这样的缩进帖子将在数据库历史记录中保持可见。

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

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


我认为这主要取决于您的访问模式。 如果每次访问可嵌入其相关帖子的实体时都需要这些帖子,则嵌入它们是有意义的( a )。 如果大多数时候你分开访问它们,那么分离它们可能会更好( b )。

或者你可以同时做两个( c ),将单独的Post实体看作规范的实体,将各个实体中嵌入的实体作为缓存版本。 这样您需要一个脚本/批处理,每次更新规范版本时都会更新嵌入的帖子。 由于信息总是存在,这使得所有的读取更容易,但是由于您需要自己保持同步,所以写入更加复杂。 此外,只有当您可以接受规范版本和嵌入版本之间的某些不一致时,此模式才可用,并且重新同步的延迟对您并不重要。

注意:这个建议与Datomic没有特别的关系,这些都是从NoSQL世界借用的技术,并不意味着我是专家。

链接地址: http://www.djcxy.com/p/65261.html

上一篇: What's the more idiomatic option in Datomic land for this schema?

下一篇: How to use / in a Datomic query?