資料庫最常見的欄位:UUID

UUID Max行銷誌

UUID 是什麼?

舉個簡單現實中的例子你的電話號碼、員工編號、銀行帳號和身份證字號等,都和 UUID 的功用非常相似,是一組唯一識別的號碼或代號。

而在網路世界中通用的唯一識別碼,我們稱為 UUID (Universally Unique Identifie),RFC 4122 中標準化了 UUID 的實作規範。

以下是幾個 UUID 的實際樣子,由 128 位元 (36 字元) 組成:

  • c2e456b2-6093-4c68-9746-2460c3ce19bb
  • efeddb6a-1471-49f1-ab67-189b5e2758e1

其中 UUID 有不同的版本,每種的使用情境不同,接下來將會為大家一一介紹:

UUID v1:

  • 組成結構:時間戳記 + MAC address 所生成
  • 缺點:
    • MAC address 是每一台電腦都會有的網卡,每一張上都會有不同的編號,如果使用 v1 要小心會有隱私性問題
    • 而現在虛擬主機的 MAC address 是會被修改,如果遇到相同的 MAC address 則會有碰撞的情況發生
    • uuid.js 統計大概有 20% 的人會使用這個版本的 UUID
  • 以下是 Python 呼叫內建 library 所產生 uuid v1 的方式:

UUID v2:

  • 是一個較少被使用和提及的版本,UUIDv2 更多的是針對特定的系統和需求設計的,它主要用於包含 POSIX 安全性資訊(如用戶 ID 和群組 ID)的 UUID,在 Python 內建 library 中並沒有實作 UUID v2。
  • 缺點:特定系統使用,且不在 Python 內建 library 裡面

UUID v3:

  • 組成結構:namespace identifier (UUID) + 字串,使用 MD5 hash 產生
  • 非隨機性的 UUID,如果你放入相同的 namespace 和字串,所產生的 UUID 會是相同
  • 以下是 Python 呼叫內建 library 所產生 uuid v3 的方式:

UUID v4:

  • 組成結構:隨機變數產生的 UUID
  • uuid.js 統計大概有 70% 的人會使用這個版本的 UUID
  • 缺點:
    • 有非常非常小機率發生碰撞 (找到重複項的機率是十億分之一)
    • 如果是當資料庫的 primary key index 時,因為是 UUID v4 是隨機的產生的,速度會比有順序的 id 還來得慢,所以才會有後面的 UUID v7 產生
  • 以下是 Python 呼叫內建 library 所產生 uuid v4 的方式:

UUID v5:

  • 組成結構:namespace identifier (UUID) + 字串,使用 SHA1 hash 產生
  • 非隨機性的 UUID,如果你放入相同的 namespace 和字串,所產生的 UUID 會是相同
  • 以下是 Python 呼叫內建 library 所產生 uuid v5 的方式:

UUID v7:

  • RFC 4122 最後更新於 16 February 2023
  • 目前 Python 內建 library 還沒有實作 v7,不過 PR 已經在審核了
  • 組成結構:前面 48 bits 由 timestamp 組成,後面是隨機組成
  • 優點:
    • 前面是由 timestamp 所組成是有順序性的,所以在當 primary key index 時速度上會遠大於 uuid v4 的版本,可以參考這篇文章有人做了速度實驗上比較:Why UUID7 is better than UUID4 as clustered index in RDBMS
    • 後面時有隨機組成,所以解決了 uuid v1 的 MAC address 的隱私性和碰撞的可能

UUID.hex

“Hex” 是 “Hexadecimal” 的縮寫,意思是「十六進位」,十六進位是由 0 到 9 和 A 到 F 所表示,所以會去除 -,這種格式使得 UUID 更適合用於 URLs 和檔案命名上的傳輸,資料庫儲存的空間也從 36 字元下降為 32 字元。

特殊的 UUID

  • nil UUID: 表示為「空」或「未指定」的 UUID,會將所有位元設為 0,00000000-0000-0000-0000-000000000000
  • max UUID: UUID 範圍內的最大值,會將所有位元設為 1,ffffffff-ffff-ffff-ffff-ffffffffffff

其他相關 ID

Snowflake ID (雪花 ID)

UUID 是由 128 位元所組成,在儲存上的長度是個硬傷,如果想要縮短長度又會怕有碰撞,要怎麼解決這個問題?我們來看看由 Twitter (X) 所提出的開發的解決方案 Snowflake ID。

在現實中每片雪花都是獨一無二,且有自己獨特的結構。所以在命名上將其命名為「Snowflake (雪花) ID」。

Snowflake ID 是由 Twitter 開發的解決方案,他們需要解決平均每秒 9000 條推文,峰值高達每秒 143199 條推文的 ID,不僅可以在其龐大的分散式伺服器中擴展,還可以產生高效的儲存 ID (大致按時間排序)。Snowflake ID 也被 Discord 和 Instagram 等公司使用。

組成結構:由 64 位元組成,相較 UUID 少了一半的長度

  • 42 bit 時間戳記
  • 10 bit 機器號碼 (or any random number you provide)
  • 12 bit 順序號碼

以下是我參考 Source code 所改寫的 python snowflake,主要是不想安裝任何的套件,使用方式簡單,僅需呼叫 snowflake_id(),即可獲得一組新的雪花 ID。

除了雪花 ID 外,以下幾種 id 都使用了類似的手法將 timestamp 加入在開頭:

Sharding & IDs at Instagram

MongoDB Object ID

ULID spec

以上是我花了點時間所整理的資訊,希望有幫助到你,那本篇就在這邊告一個段落,感謝收看 🙂

延伸閱讀

▍關於 Python 教學系列目錄:

▍關於 Flask 教學系列目錄:

▍關於 Git 教學系列目錄:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *