- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在寻找有关在 Datomic 中建模某些对多关系的方法的反馈。
假设我想为一个域设计 Datomic 模式,其中一个人有一个最喜欢的电影列表。例如,John
最喜欢的电影是 Gladiator
, Star Wars
,和Fight Club
.
在 Datomic 中对此进行建模的最明显的模式是使用基数多属性,例如:
#{["John" :person/favorite-movies "Gladiator"]
["John" :person/favorite-movies "Star Wars"]
["John" :person/favorite-movies "Fight Club"]}
这种方法可以轻松地从列表中添加或删除电影(只需使用 :db/add
和 :db/retract
),但我发现它对于重置整个电影列表来说是不切实际的 - 您本质上是需要计算旧列表和新列表之间的差异,并且必须在事务函数中运行。当列表的元素不是标量时,情况会变得更糟。
作为一种替代方法,我正在考虑使用集合实体引入间接:
#{["John" :person/favorite-movies 42]
[42 :set.string/contains "Gladiator"]
[42 :set.string/contains "Star Wars"]
[42 :set.string/contains "Fight Club"]}
通过这种方法,:person/favorite-movies
是一个基数为一、引用类型的属性,并且 :set.string/contains
是基数多、字符串类型的属性。重置列表只需创建一个新的设置实体即可:
[{:db/id "John"
:person/favorite-movies {:db/id (d/tempid :db.part/user)
:set.string/contains ["Gladiator"
"The Lord of the Rings"
"A Clockwork Orange"
"True Romance"]}}]
这种对多关系建模的方法是否存在已知的局限性?
<小时/>在关系是引用类型而不是标量类型的情况下研究这个问题更有意义,因为 Datomic 中的引用类型属性会出现一些问题。
研究一个用例也更有意义,在该用例中,关系的“重置”操作更有意义,而“最喜欢的电影”的情况并非如此。
示例:带有复选框的表单,用户可以在其中提供 Answer
到 Question
通过选择一组Option
s。用户可以更新她的Answer
到Question
。目标是对 Answer - Option
进行建模关系。
此信息模型的规范 Datomic 模式是:
:answer/id
:答案的唯一 ID(标量类型,唯一标识):option/id
:选项的唯一ID(标量类型,唯一标识):answer/selectedOptions
(引用类型,基数多)最佳答案
:set.string/contains
),您将不再拥有 favorite-movies
值的有用索引)。要获取有用的索引,您需要一对属性:例如 :person/favorite-movies
和 :person.favorite-movies/items
。:person/favorite-movies
,您需要随时知道它指向哪个集合实体,并查看集合实体的历史记录。最好的解决方案是进行细粒度的更改。例如,如果用户从集合中添加或删除特定项目,则每个添加或删除都应该是一个只有该断言或撤回的事务。集合操作是可交换的,因此两个用户攻击同一个集合不会造成任何伤害。 (除非您有派生数据,在这种情况下竞争条件很重要。)
如果您确实需要“重置集合,使其看起来像这样”操作,更好的解决方案是使用事务函数,该函数接收您想要的整个集合值并计算获取当前值所需的添加和收回成为你想要的新值。这是一个可以执行此操作的 tx 函数:
{:db/ident :db.fn/resetAttribute
:db/doc "Unconditionally set an entity's attribute's values to those provided,
retracting all other existing values.
Values must be a collection (list, seq, vector), even for cardinality-one
attributes. An empty collection (or nil) will retract all values. The values
themselves must be primitive, i.e. no map forms are permitted for refs, use
tempids directly. If the attribute is-component, removed values will be
:db.fn/retractEntity-ed."
:db/fn
#db/fn {:lang "clojure"
:params [db ent attr values]
:code (let [eid (datomic.api/entid db ent)
aid (datomic.api/entid db attr)
{:keys [value-type is-component]} (datomic.api/attribute db aid)
newvalues (if (= value-type :db.type/ref)
(into #{} (map #(if (string? %) % (d/entid db %))) values)
(into #{} values))
oldvalues (into #{} (map :v) (datomic.api/datoms db :eavt eid aid))]
(-> []
(into (comp
(remove newvalues)
(map (if is-component
#(do [:db.fn/retractEntity %])
#(do [:db/retract eid aid %]))))
oldvalues)
(into (comp
(remove oldvalues)
(map #(do [:db/add eid aid %])))
newvalues)))}}
你可以像这样使用它:
[:db.fn/resetAttribute [:person/id "John"] :person/favorite-movies
["Gladiator" "The Lord of the Rings" "A Clockwork Orange" "True Romance"]]]
;; Or to retract *all* existing values:
[:db.fn/resetAttribute [:person/id "John"] :person/favorite-movies nil]
关于database-design - Datomic:使用 'reset' 操作的一对多关系的架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42112557/
datomic 支持子查询还是可以在查询中模拟?那本质上是一个 :find在另一个 :find . 我正在尝试在查询/数据库本身而不是在应用程序中执行数据的分析转换。 最佳答案 是的,您可以在 Dat
最近听说 Datomic 作为一个现代数据库,在数据建模和可扩展性方面非常出色。但我对此知之甚少。 Datomic 数据库是否遵循 CAP 定理? 如果是,它在CAP三角形的哪个位置? 最佳答案 Da
我正在编写一个在客户端和服务器之间同步数据的应用程序,因此我经常需要检查服务器上的实体是否比客户端上的任何实体更新。 Datomic 是否保证所有新实体的 id 都大于以前存在的实体?在我将其作为程序
我正在编写一个在客户端和服务器之间同步数据的应用程序,因此我经常需要检查服务器上的实体是否比客户端上的任何实体更新。 Datomic 是否保证所有新实体的 ID 都大于以前存在的实体?在我将其作为我的
你好,我是数据数据库的新手, 我有一个与 2x 数据数据库的现有数据连接。 我使用了来自 https://docs.datomic.com/cloud/tutorial/client.html#pre
我正在尝试通过 REST API 在 Datomic 中进行“外部连接”。来自 https://github.com/Datomic/day-of-datomic/blob/master/tutori
我有一个这样的架构: [{:db/id #db/id[:db.part/db] :db/ident :person/name :db/valueType :db.type/string :
我正在使用datomic和play框架。发挥是惊人的,而原子弹则是快速的。因此,总体而言是一个很好的组合。因为我是datomic的新手(和datalog,即datomic使用的查询语言),所以我无法对
假设我的后端有一百万个文章实体,带有一个名为日期的inst属性,或者一百万个玩家 个具有名为 points 的 int 属性的实体。有什么好的方法来选择 10 篇最新文章或得分最高的球员? 我是否需要
所以我在一个没有太多内存的小型服务器上,当我尝试运行 datomic 时,它对我生气了! Launching with Java options -server -Xms1g -Xmx1g -XX:+
查看过去数据的能力似乎很有用,但我不清楚如何实际使用它。哪些领域可以从该功能中受益?也许有一些众所周知的“临时性”用例? 最佳答案 哲学 这非常困难,而且并不完全有必要列出所有域。如果您提供您考虑使用
我可以访问 repl,并且我有一个可以连接的 uri。我如何连接、查看存在哪些实体和属性、查看它们的值然后向下钻取等等?我只是在使用无需注册的免费版本。 到目前为止,这是我尝试过的: C:\progr
我在具有不同内存量(1GB - 16GB)的各种架构上运行相同的数据支持应用程序。当我批量导入数据时,我经常遇到超时或内存不足错误。 查看文档后,我偶然发现了这个 helpful document (
我想看一下 Datomic Free 用于存储的 H2 数据库中的数据。当您使用默认的“示例”设置启动事务处理程序时,数据文件进入 data展开 datomic 的目录。如果您使用 Datomic 的
我可以访问 repl,并且我有一个可以连接的 uri。我如何连接、查看存在哪些实体和属性、查看它们的值然后向下钻取等等?我只是在使用无需注册的免费版本。 到目前为止,这是我尝试过的: C:\progr
给定数据库 d 上的任意数据查询 q,是否有可能从 q 派生查询 x,当针对 d 运行时将返回在 d 上生成 q 的结果所需的所有相关数据 r? q 在 d 上的结果应该等于 q 在 r 上的结果。
我想编写一个以名字作为输入参数并返回所有匹配记录的查询。匹配应该不区分大小写。例如,我想提取所有名为 Douglass 的人。参数化,但区分大小写,这将是: (d/q '[:find (pull ?e
我是learning about Datomic queries并对如何进行“参数查询”感到好奇。 这就是我想出的: (d/q '[:find ?n ?x :where [?n :likes ?x]
我目前正在评估 Datomic 用于存储和查询构成本体的已解析符号的用例。数据库中总共有 225122 个符号(实体)(所以它是一个相当大的本体,但对于 DB 来说应该不是什么大问题)。 结构非常标准
在编写基于 Datomic 和 Clojure 的应用程序时,对等点似乎可以不受限制地访问数据。如何构建一个用户 A 无法访问用户 B 私有(private)数据的多用户系统? 我知道我可以在 Clo
我是一名优秀的程序员,十分优秀!