iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
Software Development

Datomic,內建事件溯源的資料庫。系列 第 11

先從 Datalog 談起 -- part 6 (more queries)

  • 分享至 

  • xImage
  •  

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]]

練習題

其它資源

  1. 歡迎訂閱 PruningSuccess 電子報,主要談論軟體開發、資料處理、資料分析等議題。
  2. 歡迎加入 Clojure 社群

上一篇
先從 Datalog 談起 -- part 5 (parameterized queries)
下一篇
先從 Datalog 談起 -- part 7 (more join)
系列文
Datomic,內建事件溯源的資料庫。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言