Datomic 資料庫可以視為是資料原子 (datom) 的集合,而資料原子是 5 個元素的數組 [eid attr val tx op]
。
之前我們的查詢,都只專注於查詢 eid
或是 val
這兩個元素。然而,其實 Datalog 也可以查詢其它的元素,特別是屬性 attr
和交易 tx
這兩個元素,可以提供非常有用的資訊。
這邊要對屬性做多一點的解釋:
在 SQL 資料庫,資料表綱要 (table schema) 總是以表的單位存在,表就是綱要最小的單位。在 Datomic 的話,綱要的最小單位不是表,而是欄位,且每一個欄位的綱要是可以獨立定義的,這種欄位綱要 (column schema) 又稱之為屬性。
如果我們要查 person 這種資料實體 (entity) 對應的所有綱要,我們可以先試試看如下這個查詢,它是先用 [?p :person/name]
這個子句,讓 ?p
對應到 person 這種資料實體,再用 [?p ?attr]
去比對 (match) 到資料實體所有的屬性。
[:find ?attr
:where
[?p :person/name]
[?p ?attr]]
到這一頁的底部去執行看看。
?attr
68
69
70
得到的結果卻是數字?這是怎麼一回事?
跟 SQL 資料庫不同,Datomic 用資料原子 (datom) 去儲存屬性。換言之,每一個使用者自訂的屬性,本身也都是一個資料實體,且這個資料實體會有一個系統內建的屬性 :db/ident
根據以上所述的 Datomic 運作原理,修改後的屬性查詢如下:
[:find ?attr
:where
[?p :person/name]
[?p ?a]
[?a :db/ident ?attr]]
執行的結果會是:
?attr
:person/born
:person/death
:person/name
這邊要先做個詞彙的釐清。
在一般的資料庫用語,交易 (transaction) 是指:「為了要避免競爭危害 (race condition) 時,所以將多個對資料庫操作的行為打包起來。所以要嘛就是一起成功,要嘛就是一起失敗。」然而,在 Datomic 資料庫,交易一詞差不多就是資料庫寫入的同義詞。
當我們在對 Datomic 資料庫做寫入的時候,每一次地寫入都會寫入若干個資料原子 (datom)。Datomic 資料庫會在寫入每一批資料原子的時候,自動為該批次的寫入創造一個用來記錄這次『寫入操作』的資料實體,而這個資料實體就稱之為『交易』。換言之,這個交易是可以被查詢的。
一個典型的交易資料實體長成:
[13194139534390 50 #inst "2024-08-29T17:03:57.519-00:00" 13194139534390 true]
其中:
13194139534390
是這個交易本身的實體編碼 (entity id)。50
是 :db/txInstant
對應的實體編碼 (entity id)。#inst "2024-08-29T17:03:57.519-00:00"
是交易發生的時間,也就是 timestamp如果我們要查詢 "James Cameron" 被設定為某個 person
資料實體之人名的時間,我們可以用如下的查詢找出該時間點。
[:find ?timestamp
:where
[?p :person/name "James Cameron" ?tx]
[?tx :db/txInstant ?timestamp]]