關於資料庫的資料表主鍵

資料表主鍵,用來唯一識別資料表中的資料,可以有單一主鍵或複合主鍵

以單一主鍵來說,常用的有三種,自動遞增序列號、UUID、隨機不重複碼

 

主鍵的選擇,主要有幾種考量,唯一、效能、安全性、擴充

網路上搜尋 資料庫 uuid 會有不少討論,以下列出一些整理

 

自動遞增序列號 (server side)

優點

  • 效能
    • 欄位型別為 int 或 big int,作為 DB 索引值,速度較快

缺點

  • 效能
    • 在插入一筆資料時,若其它資料表也需要知道該主鍵做為 foreign key 或欄位資料,需要多一次 DB query
    • 自動遞增會需要 lock,在 concurrency 情形下,多少會影響效率
  • 安全性
    • 作為 URI 的存取 ID 時,會透露系統資訊 (其它資源的 ID,資源總量等)
  • 擴充
    • 非全域唯一,需要多資料庫整併時,會發生資料衝突

 

UUID (server side / client side)

優點

  • 全域唯一
    • 在分散式系統上,個別產生也不會衝突
  • 效能
    • 在插入一筆資料時,若其它資料表也需要知道該主鍵做為 foreign key 或欄位資料,不需要多一次 DB query (client side)
  • 安全性
    • 因為 UUID 沒有順序性及透露其它欄位資訊,在作為 URI 的存取 ID 時,較為安全
  • 擴充
    • 資料庫整合時,也不會發生衝突

缺點

  • 效能
    • 比起 int 或 big int 較占空間,且索引效率較差 (可能在有幾十萬筆資料之後會有較明顯差異)

 

 

隨機不重複碼 (snowflake - client side)

優點

  • 全域唯一 (幾乎)
    • 以時間戳 (timestamp) 構成一部分 ID 識別碼,要衝突除非產生在同一毫秒 (ms)
    • 只要系統時間不回調,單一機器上不會衝突
    • 不同機器上,則要仰賴機器識別碼
  • 效能
    • 在插入一筆資料時,若其它資料表也需要知道該主鍵做為 foreign key 或欄位資料,不需要多一次 DB query (client side)
    • 欄位型別為 big int (20 bytes),作為 DB 索引值,速度較快
  • 安全性
    • 因為其沒有透露其它欄位資訊,在作為 URI 的存取 ID 時,較為安全
  • 擴充
    • 資料庫整合時,也不會發生衝突

缺點

  • 非全域唯一 (低機率)
    • 如上說明,除非同一台機器的時間回調,才有可能衝突