【发布时间】:2023-03-26 11:10:01
【问题描述】:
我正在考虑将 Neo4j 集成到我正在构建的 Clojure 系统中。我被问到的第一个问题是为什么我不使用 Datomic。有人对此有很好的答案吗?我听说过并看过有关 Datomic 的视频,但我对 Graph Databases 的了解还不够,无法知道 Neo4j 和 Datomic 之间的区别,它对我有什么影响?
【问题讨论】:
我正在考虑将 Neo4j 集成到我正在构建的 Clojure 系统中。我被问到的第一个问题是为什么我不使用 Datomic。有人对此有很好的答案吗?我听说过并看过有关 Datomic 的视频,但我对 Graph Databases 的了解还不够,无法知道 Neo4j 和 Datomic 之间的区别,它对我有什么影响?
【问题讨论】:
它们之间有一些根本区别:
Neo4j 和 Datomic 都可以对任意关系进行建模。它们都有效地使用 EAV(实体-属性-值)模式,因此它们都可以对许多相同的问题域进行建模除了 Datomic 的 EAV 模式还嵌入了时间维度(即 EAVT),这使得它如果您想在任意时间点对您的数据库执行高效的查询,这将非常强大。这是非不可变数据存储(包括 Neo4j)根本无法做到的。
Neo4j 和 Datomic 都提供遍历 API 和查询语言:
Neo4j 和 Datomic 都提供支持递归查询的声明式查询语言(分别为 Cypher 和 Datalog)除了Datomic 的 Datalog 通过允许自定义过滤和聚合函数提供了非常出色的查询功能> 实现为任意 JVM 代码。实际上,这意味着 Cypher's 内置函数可以被 Clojure 的 sequence library 有效地取代。这是可能的,因为运行查询的是您的应用程序,而不是数据库。
遍历 API始终由应用程序代码驱动,这意味着 Neo4j 和 Datomic 都能够使用任意遍历、过滤和数据转换代码来遍历图形除了 Neo4j 需要一个正在运行的事务,这实际上意味着它是有时间限制的。
另一个根本区别是 Datomic 查询不需要数据库协调(即没有读取事务)并且它们始终使用一致的数据快照,这意味着您可以执行多个查询和数据转换在任意时间段内,并保证您的结果将始终保持一致,并且没有事务会超时(因为没有事务)。同样,这在像绝大多数现有数据库(包括 Neo4j)这样的非不可变数据存储中是不可能做到的。这也适用于他们的遍历 API。
Neo4j 和 Datomic 都是事务 (ACID) 系统,但由于 Neo4j 使用传统的交互式事务 - 使用乐观并发控制 - 查询需要在事务内部发生(需要协调),这会对您的查询施加超时限制。实际上,这意味着对于非常复杂、长时间运行的查询,您最终会拆分查询,以便它们在特定的时间限制内完成,从而放弃数据一致性。
如果由于某种原因您的查询需要涉及大量数据(超出内存中的正常容量)并且您无法流式传输结果(因为 Datomic 提供了流式 API),那么 Datomic 可能不是一个好的合适,因为您不会利用 Datomic 的架构,迫使对等方不断驱逐他们的工作内存,执行额外的网络调用和解压缩数据段。
【讨论】: