12

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

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

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

2 回答 2

24

查看下图并阅读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 及其名称。

收容关系

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

执行业务规则

如果你想强制执行特定于应用程序的一致性规则(例如文章和评论必须有作者,评论必须有一定的长度等),你需要使用数据库函数。它们在交易者内部运行,可以原子地强制执行任意约束,中止不符合它们的交易。

于 2013-05-26T02:01:26.153 回答
5

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

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来实现,即。通过允许从评论到用户的多个引用。

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

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

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

于 2013-02-12T15:39:11.483 回答