也许我还在想sql但是我在编写简单博客的数据模式时遇到了麻烦。
我不太了解:db/cardinality
属性及其含义。
就这种类型的系统而言,我们如何建模这些关系
答案 0 :(得分:22)
查看下图并阅读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将确保收回与文章相关的所有评论。
如果要强制执行特定于应用程序的一致性规则(例如,文章和评论必须有作者,评论必须具有一定的长度等),您需要使用database functions。它们在交易者内部运行,可以原子地强制执行任意约束,中止不符合它们的交易。
答案 1 :(得分:5)
让我们首先看一下更简单的情况,即在各种实体之间存在一对多的关系(在您的情况下是用户和评论):
user ---- * comment
您可以选择对此进行建模,方法是让每个评论指向一个用户,通过属性:注释/用户 :db.type / ref 强>
这将是一个自然的模型,因为评论最多只能有一个用户。我们说基数最多为1,即。值的计数(在这种情况下是对用户的引用)不能超过1。
这可以在模式中使用:db / cardinality:db.cardinality / one 指定,这实际上是默认值,因此我们不必明确拼写出来。
请注意,由于未键入Datomic实体,因此无法强制实际基数为1,即。任何属性都可以缺席。 (实体通过其实际属性具有隐式类型。维护和解释这些类型完全取决于您的应用程序)
另一方面,如果您希望任何评论适用于多个用户,则您拥有多对多关系:
user * ---- * comment
这可以通过允许属性:comment / user 为:db / cardinality:db.cardinality / many 来实现,即。允许从用户注释的多个引用。
通过这种方式,每个用户可以被多个评论引用,每个评论可以引用多个用户。
你可以同样选择在用户而不是评论中多次提供基数。
我希望这足以帮助您入门:)