gpt4 book ai didi

data-modeling - Datomic 中的数据建模

转载 作者:行者123 更新时间:2023-12-03 05:43:44 26 4
gpt4 key购买 nike

我一直在调查Datomic ,看起来真的很有趣。不过好像有very good information on how Datomic works technically ,我还没有看到太多关于如何思考数据建模的内容。

Datomic 中数据建模的一些最佳实践是什么?有没有关于这个主题的好资源?

最佳答案

警告讲师

由于 Datomic 是新的,我对它的经验有限,因此无论如何不应将此答案视为最佳实践。对于那些具有关系背景并渴望更高效的数据存储的人,请将此作为 Datomic 的介绍。

入门

在 Datomic 中,您将域数据建模为拥有属性值的实体。因为对另一个实体的引用可以是属性的值,所以您可以简单地对实体之间的关系进行建模。

乍一看,这与在传统关系数据库中建模数据的方式并没有什么不同。在 SQL 中,表行是实体,表的列名是具有值的属性。关系由一个表行中的外键值表示,引用另一表行的主键值。

这种相似性很好,因为您可以在对域建模时勾勒出传统的 ER 图。您可以像在 SQL 数据库中一样依赖关系,但不需要弄乱外键,因为这是为您处理的。 Datomic 中的写入是事务性的,您的读取是一致的。因此,您可以以任何合适的粒度将数据分成实体,依靠连接来提供更大的图景。这是您在许多 NoSQL 存储中失去的便利,在这些存储中,通常使用大型非规范化实体来在更新期间实现某种有用的原子性级别。

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

占优势

时间本质上是所有 Datomic 数据的一部分,因此无需特别将数据历史作为数据模型的一部分。这可能是 Datomic 中谈论最多的方面。

在 Datomic 中,您的架构并未严格按照 SQL 要求的“矩形形状”进行定义。即实体1可以拥有满足模型所需的任何属性。实体不需要 NULL或不适用于它的属性的默认值。您可以根据需要向特定的单个实体添加属性。

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

不同之处在于,使用 Datomic,您可以对所有受影响的实体以原子方式进行模式更改。这意味着您可以基于任意域逻辑发出一个事务来更新所有实体的形状,用您的语言写成 [2],这将在不影响读者的情况下执行,直到提交。我不知道在关系或文档存储空间中有任何接近这种权力的东西。

您的实体也没有严格定义为“生活在一张 table 上”。您决定什么定义了 Datomic 中实体的“类型”。您可以选择明确并强制要求模型中的每个实体都有一个 :table表示它是什么“类型”的属性。或者您的实体可以通过满足每种类型的属性要求来符合任意数量的“类型”。

例如,您的模型可以要求:

  • 一个人需要属性 :name , :ssn , :dob
  • 员工需要 :name , :title , :salary
  • 居民需要 :name , :address
  • 成员(member)需要 :id , :plan , :expiration

  • 这意味着像我这样的实体:
    {: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}

    可以推断为 Person , Resident Member 但不是 Employee .

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

    最后, impedance mismatch在面向对象和关系世界之间一直让我感到沮丧。使用功能性的、以数据为中心的语言 (Clojure) 有助于实现这一点,但 Datomic 希望提供一种持久的数据存储,不需要心理体操来桥接代码和存储。

    例如,从 Datomic 获取的实体的外观和行为类似于 Clojure(或 Java)映射。它可以传递到应用程序的更高级别,而无需转换为对象实例或通用数据结构。遍历该实体的关系将懒惰地从 Datomic 获取相关实体。但是保证它们与原始查询一致,即使面对并发更新也是如此。这些实体看起来是嵌套在第一个实体中的普通旧 map 。

    在我看来,这使得数据建模更自然,而且更不用说争吵了。

    潜在的陷阱
  • 冲突的属性

    上面的示例说明了模型中的潜在缺陷。如果你后来决定 :id也是 Employee 的一个属性?解决方案是将您的属性组织到命名空间中。所以你会同时拥有 :member/id:employee/id .提前这样做有助于避免以后发生冲突。
  • 无法更改属性的定义(尚)

    一旦你在你的 Datomic 中定义了一个特定类型的属性,索引与否,唯一的等等,你以后就不能改变它。我们在谈 ALTER TABLE ALTER COLUMN在这里用 SQL 的说法。现在,您可以使用正确的定义创建替换属性并移动现有数据。

    这听起来可能很可怕,但事实并非如此。由于事务是序列化的,您可以提交一个创建新属性、将数据复制到其中、解决冲突并删除旧属性的事务。它将在不受其他事务干扰的情况下运行,并且可以利用您的母语中的特定于域的逻辑来完成它的工作。当您发出 ALTER TABLE 时,这本质上是 RDBMS 在幕后所做的事情。 ,但你命名规则。
  • 不要做“糖果店里的 child ”

    灵活的模式并不意味着没有数据模型。我建议一些预先计划以理智的方式对事物进行建模,就像您对任何其他数据存储所做的一样。在必要时利用 Datomic 的灵活性,而不仅仅是因为您可以。
  • 避免存储大量、不断变化的数据

    Datomic 不是用于 BLOB 或不断变化的超大数据的良好数据存储。因为它保留了以前值的历史记录,并且还没有清除旧版本的方法(还没有)。这种东西几乎总是更适合像 S3 这样的对象存储。更新:有一种方法可以到 disable history on a per-attribute basis .更新:现在还有一种方法可以到 excise data ;然而,存储对外部对象的引用而不是对象本身可能仍然是处理 BLOB 的最佳方法。将此策略与使用 byte arrays 进行比较.

  • 资源
  • Datomic mailing list
  • Freenode 上的 IRC channel #datomic

  • 笔记
  • 我指的是行意义上的实体,而不是更恰本地描述为实体类型的表格意义上的实体。
  • 我的理解是目前支持 Java 和 Clojure,但将来可能会支持其他 JVM 语言。
  • 关于data-modeling - Datomic 中的数据建模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10357778/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com