西雅图示例中未使用db / isComponent.可以公平地说:Datomic中的db.type / ref关系不是“强制执行”(使用关系数据库外键依赖概念) – 除非你用db / isComponent设置它们吗?
:db / isComponent用于指定包含关系,即来自UML的组合关系.你可以把它想象成一种“A有B”的关系.建模简单博客的一部分就是一个明显的例子:
在Datomic中,如果您使用:db / isComponent属性作为上述文章 – 评论关系的一部分,则撤消文章也会收回其所有评论.有关完整的代码示例,请查看Datomic: containment relationships i.e. db/isComponent要点.
请注意,Datomic中没有任何内容可以阻止您将错误类型的实体添加到:db.type / ref属性.在上面的示例中,Datomic将允许您添加对“作者”实体(而不是注释)的引用,而不需要真正关心.这就是外键约束发挥作用的地方.
Datomic使用:db.type / ref属性定义关系,但并未真正强制执行任何有关它们的任何内容.要使用任意外键约束,您需要使用database functions.
在您提到的西雅图数据库中:社区/ orgtype属性应该仅引用一些允许的枚举值(:community.orgtype / *),但实际上在运行时没有强制执行:
为了说明如何在Datomic中实现任意外键约束,我编写了一个数据库函数(称为add-fk),它可以防止错误的枚举值与:community / orgtype属性相关联.
有关完整的代码示例,请查看Datomic: database functions and foreign-key constraints要点.例如,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]]