【问题标题】:modelling multiple many-to-many relationships in datomic在 Datomic 中建模多个多对多关系
【发布时间】:2013-01-21 09:51:02
【问题描述】:

也许我还在考虑 sql,但我在为一个简单的博客编写 datomic 架构时遇到了麻烦。 我不太明白:db/cardinality 属性及其含义。

就这种类型的系统而言,我们如何对这些关系进行建模

  • 系统支持多用户
  • 每个用户可能有很多类别
  • 每个用户可能有很多文章
  • 每个类别可能有很多用户
  • 每个类别可能有很多文章
  • 每篇文章可能有多个 cmets
  • 每条评论都有一个用户

【问题讨论】:

  • In terms of this type of system, how do we model these relationships 不确定您是否希望有人为您创建整个相应的 Datomic 架构...? “多对多关系”是不言自明的,不需要特定业务的示例
  • ` 我不太了解 :db/cardinality 属性及其含义` 那么这就是你现在真正的问题了。有大量的学习资源,从文档到 InfoQ 演示文稿再到 github.com/Datomic/day-of-datomic

标签: clojure datomic


【解决方案1】:

让我们首先看一个更简单的情况,即您在各种实体(在您的情况下为用户和 cmets)之间存在一对多关系:

user ---- * comment

您可以选择通过让每个评论精确指向一个用户来进行建模,通过一个属性,例如 :comment/user 类型为 :db.type/ref强>。

这将是一个自然模型,因为一条评论最多只能有一个用户。我们说基数最多为1,即。值的计数(在这种情况下是对用户的引用)不能超过 1。

这可以通过 :db/cardinality :db.cardinality/one 在模式中指定,这实际上是默认值,因此我们不必明确说明。

请注意,由于未键入 Datomic 实体,因此不可能强制实际基数为 1,即。任何属性都可以不存在。 (实体通过其实际属性具有隐式类型。这些的维护和解释完全取决于您的应用程序)

另一方面,如果您希望任何评论适用于多个用户,则具有多对多关系:

user * ---- * comment

这可以通过允许属性 :comment/user:db/cardinality :db.cardinality/many 来实现,即。通过允许从 cmets 到用户的多个引用。

这样每个用户可以被多个cmet引用,每个评论可以引用多个用户。

您同样可以选择在用户而不是 cmets 上引用基数。

我希望这足够清楚,可以帮助您入门 :)

【讨论】:

    【解决方案2】:

    查看下图并阅读https://gist.github.com/a2ndrade/5651419 处的完整代码示例(架构、示例数据和查询)。它应该可以帮助您了解如何在 Datomic 中对数据进行建模。

    查询

    请注意,由于 Datomic 中的关系是双向的,并且您可以使用简单的 Datalog 查询来检索其余信息,因此某些关系并未显式建模。例如查询:

    (d/q '[:find ?cid ?c
       :in $ ?u
       :where
       [?uid :user/username ?u]
       [?aid :article/category ?cid]
       [?aid :article/author ?uid]
       [?cid :category/name ?c]]
     (d/db conn) "john.smith")
    

    查找用户(“john.smith”)为其撰写文章的所有类别 ID 及其名称。

    收容关系

    一个重要的建模决策是让文章指向 cmets 并将关系标记为 :db/isComponent,因为 cmets 不应单独存在,而应作为文章的一部分。如果文章本身被撤回,Datomic 将确保撤回与文章关联的所有 cmets。

    执行业务规则

    如果你想强制执行特定于应用程序的一致性规则(例如,文章和 cmets 必须有作者,cmets 必须有一定的长度等)你需要使用database functions。它们在事务器内部运行,可以自动执行任意约束,中止不符合它们的事务。

    【讨论】:

      猜你喜欢
      • 2019-08-21
      • 1970-01-01
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多