7

Datomic Sc​​hema doco中,他们提到了一个名为db/isComponent. 这似乎是指由 定义的关系:db.type/ref

西雅图db/isComponent示例中未使用 。公平地说,:db.type/refDatomic 中的关系不是“强制”的(使用关系数据库外键依赖概念)-除非您将它们设置为db/isComponent?

4

2 回答 2

13

遏制关系 ( :db.type/ref+ :db/isComponent)

:db/isComponent用于指定包含关系,即来自 UML 的组合关系。您可以将其视为“ AB ”的关系。一个简单博客的建模部分就是一个明显的例子:

文章评论

在 Datomic 中,如果您将:db/isComponent属性用作上述文章-评论关系的一部分,撤消文章也会撤消其所有评论。有关完整的代码示例,请查看Datomic:包含关系,即 db/isComponent要点。

请注意,Datomic 中没有任何内容可以阻止您将错误类型的实体添加到:db.type/ref属性中。在上面的示例中,Datomic 允许您添加对“作者”实体的引用(而不是评论),而无需真正关心。这就是外键约束发挥作用的地方。

外键约束(:db.type/ref+数据库函数)

Datomic 使用:db.type/ref属性定义关系,但并没有真正强制执行任何关于它们的事情。要使用任意外键约束,您需要使用数据库函数

在您提到的西雅图数据库中,:community/orgtype属性应该只引用一些允许的枚举值(:community.orgtype/*),但实际上在运行时没有强制执行:

在此处输入图像描述

为了展示如何在 Datomic 中实现任意外键约束,我编写了一个数据库函数(称为add-fk),以防止错误的枚举值与:community/orgtype属性相关联。

有关完整的代码示例,请查看Datomic:数据库函数和外键约束要点。例如,add-fk数据库函数行为如下所示:

 ;; will succeed
 [[:db/add #db/id [:db.part/user] :community/name "15th Ave Community"]
  [:add-fk #db/id [:db.part/user] :community/orgtype :community.orgtype/personal]])

 ;; will fail
 [[:db/add #db/id [:db.part/user] :community/name "15th Ave Community"]
  [:add-fk #db/id [:db.part/user] :community/orgtype :community.type/email-list]])
 ;; java.lang.Exception: :community.type/email-list is not one of 
 ;; [[:community.orgtype/community], [:community.orgtype/commercial], 
 ;; [:community.orgtype/personal], [:community.orgtype/nonprofit]]
于 2013-06-16T20:05:49.633 回答
3

不,在 Datomic 中, db/isComposite 指的是 OOP/UML 意义上的组合(与聚合相反)。

将 db/isComposite 设置为 true,当您收回实体时,所有子组件也会被收回。当您触摸一个实体时,它的所有子组件实体都会被递归地触摸。

考虑来自电子商务世界的 2 个不同的关系示例:

1)客户----用户偏好

通常这是组合。首选项实体生命周期取决于客户实体生命周期。在 Datomic 中,Customer 上的 userPreferences ref 应该将 db/isComposite 属性设置为 true。

2)客户----OrderItem

通常这是聚合。即使删除了 Customer,OrderItem 也可以存在。这是 Datomic 中的默认引用类型。

关系模型将这两个依赖项都实现为外键,因此就表示而言,答案是:是的,db/isComponent 可以在 RDBMS 中表示为具有 CASCADE 操作的引用约束(FOREIGN KEY),但从概念上讲,它并不等效。

于 2013-03-23T15:51:52.227 回答