【问题标题】:Datomic - db/isComponent equivalent to enforcing a foreign key dependency?Datomic - db/isComponent 相当于强制执行外键依赖?
【发布时间】:2013-03-13 06:45:59
【问题描述】:

Datomic Schema doco 中,他们提到了一个名为db/isComponent 的架构属性。这似乎是指:db.type/ref 定义的关系。

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

【问题讨论】:

    标签: schema foreign-key-relationship datomic enforcement


    【解决方案1】:

    收容关系 (:db.type/ref + :db/isComponent)

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

    在 Datomic 中,如果您使用 :db/isComponent 属性作为上述文章-评论关系的一部分,撤消文章也会撤消其所有 cmets。如需完整的代码示例,请查看Datomic: containment relationships i.e. db/isComponent gist。

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

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

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

    在您提到的西雅图数据库中,:community/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]]
    

    【讨论】:

      【解决方案2】:

      没有。在 Datomic 中,db/isComposite 指的是 OOP/UML 意义上的 composition(而不是 aggregation)。

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

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

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

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

      2) 客户----订单项

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

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

      【讨论】:

        猜你喜欢
        • 2011-03-02
        • 2012-08-06
        • 2016-06-04
        • 1970-01-01
        • 1970-01-01
        • 2019-01-09
        • 1970-01-01
        相关资源
        最近更新 更多