Datomic 數據庫詳細介紹
Datomic 是一個由 Rich Hickey(Clojure 語言創始人)設計的 不可變、時間感知、分布式數據庫,專為現代應用程序設計,強調 數據不變性(immutability)、查詢靈活性和可審計性。它結合了 關系數據庫的查詢能力、文檔數據庫的靈活性、圖數據庫的關聯能力,同時引入了 時間旅行(time travel) 和 事件溯源(event sourcing) 的概念。
1. Datomic 的核心特性
(1) 不可變數據模型(Immutable Data)
- 所有數據一旦寫入 不可修改,只能追加(append-only)。
- 任何變更都會生成新的 數據點(datom),保留完整歷史記錄。
- 類似于 Git 的版本控制,可以查詢任意時間點的數據狀態。
(2) 時間感知(Time Travel)
- 每個數據變更都帶有 時間戳(transaction time)。
- 可以查詢 過去某個時刻的數據庫狀態(類似
AS OF
查詢)。 - 適用于 審計、回滾、數據分析 等場景。
(3) 基于 Datalog 的查詢語言
- 使用 Datalog(類似 Prolog 的邏輯查詢語言)進行查詢。
- 比 SQL 更靈活,支持遞歸查詢、規則定義等。
- 示例查詢:
(d/q '[:find ?name:where[?e :user/name ?name][?e :user/age ?age][(> ?age 30)]]db)
(4) 分布式架構
- 分離計算與存儲:
- Peer(應用層)負責查詢和事務邏輯。
- Transactor(事務協調器)處理寫入。
- Storage Service(存儲后端)可以是 DynamoDB、PostgreSQL、Cassandra 等。
- 支持 水平擴展(讀擴展),但寫入由單個 Transactor 處理(類似單寫多讀)。
(5) Schema-on-Read(讀取時模式)
- 不需要預先定義嚴格的表結構,可以動態添加屬性。
- 類似于 NoSQL,但支持強類型(
:db/valueType
可以是:string
、:long
、:ref
等)。
2. Datomic 的數據模型
Datomic 的數據模型由 Datoms(四元組)構成:
[EntityID, Attribute, Value, TransactionID, Added?]
- EntityID:唯一標識實體(類似主鍵)。
- Attribute:屬性(如
:user/name
)。 - Value:屬性值(如
"Alice"
)。 - TransactionID:事務 ID(時間戳)。
- Added?:
true
(新增)或false
(刪除)。
示例 Datom
[123 :user/name "Alice" 456 true] ;; 事務 456 添加了用戶 123 的名字 "Alice"
3. Datomic 的架構
Datomic 采用 三層架構:
- Peer(客戶端):
- 運行在應用進程內(如 JVM)。
- 負責查詢、緩存、部分計算。
- Transactor(事務處理器):
- 單點寫入(類似 Kafka 的 leader)。
- 確保 ACID 事務。
- Storage Service(存儲后端):
- 可以是 DynamoDB、PostgreSQL、Cassandra 等。
- 存儲 Datoms 和索引。
4. Datomic 的查詢(Datalog)
Datomic 使用 Datalog 查詢,比 SQL 更靈活:
基本查詢
(d/q '[:find ?name ?age:where[?e :user/name ?name][?e :user/age ?age]]db)
規則(Rules)
(d/q '[:find ?ancestor:in $ % :where(parent ?p ?c)(parent ?ancestor ?p)]db'[[(parent ?a ?b)[?a :person/parent ?b]]])
5. Datomic 的事務
事務通過 Transactor 提交,返回 事務報告(TxReport):
(d/transact conn [{:db/id "temp-id":user/name "Bob":user/age 35}])
- 每個事務生成一個 TxID(可用于時間查詢)。
- 支持 CAS(Compare-and-Swap) 操作。
6. Datomic 的適用場景
- 審計與合規(完整歷史記錄)。
- 事件溯源(Event Sourcing)(如金融、醫療)。
- 復雜查詢(圖查詢、遞歸查詢)。
- 微服務架構(分離讀寫,避免 ORM)。
7. Datomic 的局限性
- 寫入擴展性:Transactor 是單點(寫入吞吐受限)。
- 成本:商業版較貴(云版按查詢收費)。
- 學習曲線:Datalog 和不可變模型需要適應。
8. Datomic vs. 其他數據庫
特性 | Datomic | SQL 數據庫 | MongoDB | Neo4j |
---|---|---|---|---|
數據模型 | 不可變 Datoms | 表+行 | JSON 文檔 | 圖(節點+邊) |
查詢語言 | Datalog | SQL | MQL | Cypher |
歷史查詢 | ? 支持 | ? 有限 | ? 有限 | ? 有限 |
擴展性 | 讀擴展 | 讀寫擴展 | 讀寫擴展 | 讀擴展 |
9. Datomic 的替代方案
- XTDB(開源,類似 Datomic)。
- Crux(開源,支持 SQL 和 Datalog)。
- DuckDB(嵌入式 OLAP,適合分析)。
10. 總結
Datomic 是一個 革命性的數據庫,特別適合:
- 需要完整歷史記錄的應用(如金融、法律)。
- 復雜查詢場景(圖、遞歸)。
- Clojure 生態(原生集成)。
但它的 寫入擴展性和商業成本 可能限制某些場景。如果需要一個 開源替代品,可以考慮 XTDB 或 Crux。
參考資料