iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0
Software Development

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

主鍵 (primary key) 與資料實體編碼 (entity id)

  • 分享至 

  • xImage
  •  

不知道大家有沒有跟我一樣,曾經為了該如何設計 SQL 資料表的主鍵 (primary key) 而困擾不已?

每次遇到這種問題,第一個要考慮的就是:

  1. 要用自然鍵 (natural key) 來當主鍵嗎?自然鍵是業務規則 (business) 中所擁有的一個或多個的資料屬性。這個作法初期很省事。
  2. 要用代理鍵 (surrogate key) 來當主鍵嗎?這種主鍵可以與業務意義 (business meaning) 解耦,將來修改的彈性較高。此外,部分的表 (table) 因為它是某個資料實體的一小部分,它沒有可以做為自然鍵的資料屬性,這種表就必須使用代理鍵。

如果說決定了要使用代理鍵,接下來的問題就是,該怎麼決定代理鍵的資料型態:

  • 遞增整數
  • 字串 (UUID)

然後,又要考慮會不會有列舉攻擊 (enumeration attacks)、效能夠不夠好?到底是要使用可迴避列舉攻擊的整數、還是要選擇有加強效能的 UUID ?

Datomic 幫你做了主鍵的決定

在 Datomic 的世界,主鍵就是資料實體編碼 (entity id),就是這麼簡單。

有一個簡單的預設選項對我來講這是一大解脫。這有點像是從 C++ 語言改成寫 Java 之後,就再也不用去想記憶體的 new/delete 。從 JavaScript 改寫 Clojure 之後,所有的容器類別都是 persistent collection,就再也不用去想什麼時候需要 deepClone() 、什麼時候不需要了。做應用軟體開發,光是要想清楚業務規則就已經夠累人了,如果使用的工具還動不動提供五、六種效能與安全性的設計排列組合,真的是會嚴重的決策疲勞,讓人很想要隨便亂選一個。

最佳實踐

由於 Datomic 讓每一個資料實體,都有同一型態的資料實體編碼,所以這也可以推導出一些對應的最佳實踐。

  1. 查詢的時候,儘量利用資料實體編碼來做 join 。效能會最好。
  2. 資料實體編碼不應暴露給外界,比方說, API 的 path 就不應該直接使用資料實體編碼。
  3. 外界要使用的鍵,應該要指定唯一性的條件限制 (unique identity constraint)

註:條件限制參考 Day26

列舉類型 (enum type) 與 :db/ident

Day 24 我們有列出,在 Datomic 資料庫裡,屬性可以使用的資料型別。在眾多可以使用的資料型別中,相對於傳統的 SQL 資料庫,缺少了列舉類型 (enum type)。

然而,其實 Datomic 對於列舉類型的作法有獨特的最佳實踐。該最佳實踐由主要有三點構成:

  1. 使用 :db/ident 來定義列舉類型,列舉類型本身會是資料實體 (entity)。
  2. 用來指向列舉類型的屬性,它的資料型態設定為 :db.type/ref
  3. 列舉類型的名稱可以自動轉換成它的資料實體編碼。

使用列舉類型的例子

  • 定義屬性與列舉類型
[
;; 定義列舉類型 :country/CA
{:db/ident :country/CA}

;; 定義列舉類型 :country/JP
{:db/ident :country/JP}

;; 定義屬性 :artist/country
;; 並且讓這個屬性可以指向某個列舉類型的資料實體
{:db/ident :artist/country
 :db/valueType :db.type/ref
 :db/cardinality :db.cardinality/one
 :db/doc "An artist's country of residence"}
]
  • 寫入真實的資料
[{:artist/name "Leonard Cohen"
  :artist/country :country/CA}]

在寫入真實資料的時候,:artist/country 由於是 :db.type/ref 的資料型態,所以它右邊對應的值應該要是資料實體編碼 (entity id)。然而,上述的程式碼是正確的,因為在 Datomic ,凡是用 :db/ident 定義的列舉類型,都可以自動轉換成它的資料實體編碼。

參考資料

  1. Data Modeling

其它資源

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

上一篇
Datomic 的寫入
下一篇
條件限制 (constraints)
系列文
Datomic,內建事件溯源的資料庫。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言