Datomic表模型

时间:2016-05-15 16:24:27

标签: datomic

我有一个应用程序需要一个包含一组产品的数据库,其中每个产品都可以有一组表。最终用户应该能够添加新产品并为产品定义新表。因此每个表都有一组由用户指定的列。然后,用户可以使用数据行填充表。每个表只属于一个产品。

最终用户还应该能够在特定时间点(在特定交易时)查看表格。

我如何在Datomic中为此制作模式,以便查询它尽可能高效?

1 个答案:

答案 0 :(得分:1)

我会使用4种实体类型:产品,表格,列和行。

产品和表之间的关系最好由:table/product到一个ref属性处理,但:product/tables到多个组件引用属性也可以工作(后者不强制执行 - 多对多的关系。)

同样,我会使用:column/table:table/columns属性。我还有一个:column/name字符串属性,可能还有一个:column/type枚举属性。

最难的部分是对行进行建模。

一个诱人的解决方案就是每列创建一个属性 - 我实际上认为这是个坏主意,Datomic属性并不适合这种动态使用。特别是,模式属性存储在Peer上的缓存中,并不意味着变大。 (我可能错了,所以如果Datomic团队的某个人能够确认,那就太好了。)

相反,我会有几十个可重复使用的:row/cell-0:row/cell-1:row/cell-2等。'单元格位置'所有表共享的属性。每个实际列都将在创建时映射到一个:column/position属性。

如果行可以有多种数据类型,那就更难了,你必须为每个(类型,位置)对创建一个属性。

然后每行基本上由:row/table属性和上面的单元格位置属性组成。

这是一个Datalog查询,可让您阅读整个表格

[:find ?row ?column-name ?val :in $ ?table :where
 [?column :column/table ?table]
 [?row :row/table ?table]
 [?row ?pos ?val]
 [?column :column/position ?pos]
 [?column :column/name ?column-name]]

请注意,只有在您希望使用Datalog直接针对Datomic数据库查询表时,上述所有内容才有用。但是将序列化并将它们存储为blob也是完全可以的 - 特别是如果它们很小的话;稍后,你拉出blob,反序列化它,然后你也可以用Datalog查询。如果表格粗略用于此用途,也许你可以用行来做。