首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Datomic中的数据建模有哪些最佳实践?

Datomic中的数据建模有哪些最佳实践?
EN

Stack Overflow用户
提问于 2018-04-24 00:48:44
回答 2查看 0关注 0票数 0

我一直在研究Datomic,它看起来非常有趣。尽管似乎有关于Datomic如何在技术上工作的非常好的信息,但我还没有看到如何考虑数据建模。

Datomic中的数据建模有哪些最佳实践?这方面有没有很好的资源?

EN

回答 2

Stack Overflow用户

发布于 2018-04-24 09:43:18

注意Lector

由于Datomic是新的,我的经验很有限,因此不应以任何方式将此答案视为最佳实践。把它作为Datomic的介绍给那些具有关系背景和渴望更高效的数据存储的人。

入门

在Datomic,你为你的域数据模型的实体是具有价值属性。因为另一个参考实体可以是的的属性,你可以模拟关系之间的实体简单。

首先看,这与数据在传统关系数据库中建模的方式并不完全相同。在SQL中,表行是实体和具有的表的列名称属性。甲关系由外键表示在表格中的一行引用主键价值另一个表行的。

这种相似性很好,因为可以在建模域时勾画出传统的ER图。可以像在SQL数据库中一样依赖关系,但不需要混淆外键,因为这是为你处理的。在Datomic中写入是事务性的,读取是一致的。因此,可以将数据分隔为任何粒度感觉良好的实体,依靠联接来提供更大的图像。对于许多NoSQL商店来说,这是一个很方便的地方,在这些商店中,通常会有大量非规范化实体在更新期间实现一些有用的原子级别。

在这一点上,你有一个良好的开端。但是Datomic比SQL数据库更灵活。

利用

时间本质上是所有Datomic数据的一部分,所以不需要将数据的历史记录作为数据模型的一部分。这可能是Datomic最受关注的一个方面。

在Datomic中,模式不是在SQL所需的“矩形”中严格定义的。也就是说,一个实体1可以拥有任何它需要的属性来满足你的模型。实体不需要具有NULL或不适用于其的属性的默认值。如果认为合适,可以将属性添加到特定的单个实体。

因此,可以随时改变单个实体的形状,以响应域中的更改(或更改您对域的理解)。所以呢?这与文档存储(如MongoDB和CouchDB)不同。

与Datomic不同的是,可以在所有受影响的实体上自动执行模式更改。这意味着你可以发出一个事务更新所有实体的形状,基于任意域逻辑写在你的语言 [2],这将不会影响读者提交之前执行。在关系或文档存储空间中,我没有发现任何与这种功能相近的东西。

决定什么定义了Datomic中实体的“类型”。你可以选择明确,并且要求模型中的每个实体都有一个:table暗示“类型” 的属性。或者实体只需满足每种类型的属性要求即可符合任意数量的“类型”。

例如,模型可能要求:

  • 一个人需要的属性:name:ssn:dob
  • 雇员需要:name:title:salary
  • 居民要求:name:address
  • 一位成员要求:id:plan:expiration

这意味着像我这样的实体:

代码语言:javascript
复制
{:name "Brian" :ssn 123-45-6789 :dob 1976-09-15 
 :address "400 South State St, Chicago, IL 60605"
 :id 42 :plan "Basic" :expiration 2012-05-01}

可以推断为PersonResident Member 不是Employee

Datomic查询在Datalog中表达,并且可以包含用自己的语言表达的规则,引用未存储在Datomic中的数据和资源。可以将数据库函数作为Datomic中的第一类值存储。这些类似于SQL中的存储过程,但可以作为事务内部的值进行操作,也可以用语言编写。这两个功能都可让你以更加以领域为中心的方式表达查询和更新。

最后,面向对象和关系世界之间的阻抗不匹配一直让我感到沮丧。使用功能性,以数据为中心的语言(Clojure)可以帮助解决这个问题,但Datomic希望提供一种持久的数据存储,不需要心理体操从代码到存储。

作为一个例子,从Datomic获取的实体看起来像Clojure(或Java)映射。它可以传递到更高级别的应用程序,而不需要翻译成对象实例或通用数据结构。遍历该实体的关系将会懒惰地从Datomic获取相关实体。但保证它们将与原始查询保持一致,即使面对并发更新。这些实体看起来是嵌套在第一个实体内的普通旧地图。

这使得数据建模更加自然和多,更不用说在我看来是一场斗争。

潜在的缺陷

  • 相冲突的属性 上面的例子说明了你的模型中潜在的缺陷。如果你以后决定这:id也是一个属性Employee?解决方案是将属性组织到名称空间中。所以你会有两个:member/id:employee/id。提前做此事有助于避免以后发生冲突。
  • 属性的定义不能改变(还) 一旦将Datomic中的属性定义为特定类型,索引或不索引,唯一等,将无法在以后更改该属性。我们在ALTER TABLE ALTER COLUMN这里用SQL的说法来谈论。目前,可以使用正确的定义创建替换属性并移动现有数据。 这听起来可怕,但事实并非如此。因为事务是序列化的,所以可以提交一个创建新属性,将数据复制到它,解决冲突并删除旧属性。它将在没有其他事务干扰的情况下运行,并且可以利用本地语言中特定于领域的逻辑来完成这件事。这基本上就是RDBMS在发布后在幕后做的事情ALTER TABLE,但是将规则命名。
  • 灵活的模式并不意味着没有数据模型。我建议一些前期规划以一种理智的方式对事物进行建模,与其他数据存储一样。当你需要时,利用Datomic的灵活性,不仅仅是因为你可以。
  • 避免存储大量不断变化的数据 对于BLOB或不断变化的非常大的数据,Datomic不是一个好的数据存储。因为它保留了之前值的历史记录,并且没有清除旧版本的方法(尚未)。这种东西几乎总是适合像S3这样的对象存储。有一种方法可以根据每个属性禁用历史记录

资源

笔记

  1. 我的意思是在行意义上的实体,而不是表格意义,它更适当地描述为实体类型。
  2. 我的理解是,Java和Clojure目前得到支持,但未来可能会支持其他JVM语言。
票数 0
EN

Stack Overflow用户

发布于 2018-04-24 10:48:35

  1. 如果存储了许多类似但不相同的“类型”或模式的实体,请在模式中使用类型关键字,如 [:db/add #db/id[:db.part/user] :db/ident :article.type/animal] [:db/add #db/id[:db.part/user] :db/ident :article.type/weapon] [:db/add #db/id[:db.part/user] :db/ident :article.type/candy] {:db/id #db/id[:db.part/db] :db/ident :article/type :db/valueType :db.type/ref :db/cardinality :db.cardinality/one :db/doc "The type of article" :db.install/_attribute :db.part/db}
  2. 当你阅读,从查询得到实体的IDS和使用datomic.api/entity以及eid和多方法,如果nescessary调度类型上分析它们,因为很难让所有属性的一个很好的查询在一些更复杂的架构。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100003303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档