iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
Software Development

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

先從 Datalog 談起 -- part 3 (data patterns)

  • 分享至 

  • xImage
  •  

之前在解釋基本查詢的運作時,提到了

[?e :person/name "Ridley Scott"] 這個條件比對整個資料庫的內容,:where 子句裡的 ?e 是一個未知的變數。

這邊,我們多定義一些詞彙以讓日後的用語更精確。

  • 資料模式 (data pattern)
    • [?e :person/name "Ridley Scott"] 這種出現在 :where 之後的向量,稱之為資料模式。
    • 由於資料模式通常是用來對 Datomic 資料庫做查詢,所以資料模式可以是一個內含 [E A V Tx] 的向量。另一方面,很多時候,我們並不在意 Tx 的值,所以寫資料模式時,常常也只寫 [E A V]
    • 資料模式內的元素有三種可能性:
      • 變數 (variable),它可以綁定 (bind) 到新的值。
      • 常數 (constant),它是固定值,通常是 keyword 或是數字、字串。
      • 底線 (blank),它可以匹配到任何值,但是不會被使用,只是用來佔位。(註1)

多個資料模式,共用一個變數

來看一個比較複雜的查詢:

[:find ?title
 :where
 [?e :movie/year 1987]
 [?e :movie/title ?title]]

這個查詢是要找出,所有 1987 年的電影的名稱 (title)。這邊有兩點值得注意:

  1. 這個查詢有兩個資料模式,且兩個資料模式裡使用同一個變數 ?e
    • 在 Datalog 裡,當有多個資料模式使用同一個變數時,在多個資料模式裡的變數都會綁定到同一個值。
  2. 資料模式的順序並不重要。順序會影響效能,但是不會影響語意。換言之,上述的查詢也可以改寫成如下,而結果是完全一樣的。
[:find ?title
 :where
 [?e :movie/title ?title]
 [?e :movie/year 1987]]

上述的查詢如果改寫成對應的 SQL 的話:

SELECT title
FROM movie
WHERE year = 1987; 

多個資料模式,且多個變數

如果我們想查的是:「誰主演了 "Lethal Weapon" 這部電影?」可以寫成如下的查詢:

[:find ?name
 :where
 [?m :movie/title "Lethal Weapon"]
 [?m :movie/cast ?p]
 [?p :person/name ?name]]

資料模式的部分,可以理解成:

  • [?m :movie/title "Lethal Weapon"]
    • 比對電影的名稱 "Lethal Weapon",可以推得電影的實體編碼 (entity id) ?m 應綁定的值。
  • [?m :movie/cast ?p]
    • 如果已推得 ?m 的值的前提之下,可以推得人的實體編碼 ?p
  • [?p :person/name ?name]
    • 如果已推得 ?p 的值的前提之下,可以推得人的名字 ?name

上述的查詢如果改寫成對應的 SQL 的話:

SELECT person.name
FROM movie 
INNER JOIN person 
ON movie.cast = person.id
WHERE movie.title = "Lethal Weapon"; 

不知道大家有沒有發現, inner join 在不知不覺中就已經發生了。

練習題

註:

  1. 佔位一詞可能有點抽象,以下用一個實例來解釋。

下方的查詢要找出有演出過電影、且叫做 "Clinton Eastwood" 的人的實體編碼 (entity id)。

[:find ?p
 :where
 [_ :movie/cast ?p]
 [?p :person/name "Clinton Eastwood"]]

因為需要確保,這個人有演出過電影,所以需要寫 [_ :movie/cast ?p] ,但我們並不在意是哪部電影,有就好,這時就使用底線去佔據這個資料模式裡的 E位置

其它資源

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

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

尚未有邦友留言

立即登入留言