UUID v4 vs UUID v7 vs ULID:你應該使用哪個唯一ID?
對於資料庫金鑰,API和分散式系統,與效能,隱私和格式權衡進行隨機 UUID v4,時間順序 UUID v7 和 ULID 的比較。
· 5 分鐘閱讀
自動增加的整數幾十年來一直是預設的初級金鑰。它們是緊且快速的,但它們需要一箇中央資料庫來分配數字,洩露你有多少記錄,。全球獨一無二的識別符解決了這些問題:任何伺服器,移動應用程式或離線客戶端都可以建立一個永遠不會碰撞的ID。問題在於是哪種。本指南比較了2026年最流行的三個選項:UUID版本 4,UUID版本 7 和 ULID。
一個快速的更新 UUID
UUID (通用唯一識別符號) 是一個128位的值,通常用32個十六進位制數字寫成五組:
550e8400-e29b-41d4-a716-446655440000
目前的標準RFC 9562 (於2024年釋出,取代RFC 4122),定義了幾個版本。一些位符號編碼版本和變體;其餘取決於版本。第三組始於版本號,所以你可以一眼看出v4和v7。
UUID v4:完全隨機
一個版本4 UUID 包含 122 個隨機位加上 6 個版本和變體的固定位。
優勢
- 每種語言和資料庫都有內建的函式,例如JavaScript中的
crypto.randomUUID()或PostgreSQL中的gen_random_uuid()。 - 沒有時間,沒有機器識別符號,沒有序列。
- 碰撞的可能性是微不足道的。需要生成約2.7 × 10^18的ID,
弱點
- 隨機順序會損害資料庫索引。在PostgreSQL,MySQL和SQL伺服器中使用的B樹索引,在新金鑰以不斷增加的順序到達時表現最好。隨機鍵會在索引中出現,導致頁面分裂,快取位置不好,。在大型表格中,插入吞吐量可能會顯著下降,索引會比必要的更大。
- 不能按建立時間進行排序,所以需要一個單獨的
created_at列來進行時間查詢。
UUID v7:時間順序
版本7將 48 位 Unix 時間放在前面的毫秒,其次是 74 位隨機性 (一些實現將其部分作為在同一毫秒內排序的計時器)。
01928c3e-5b7a-7c4d-9f3e-2a1b4c5d6e7f
└─timestamp─┘ └version 7
優勢
- 新的ID大致增加,所以插入新增到索引的末尾像自動增量鍵。這使得索引緊,寫作快。
- 按建立時間按ID排序排序,這使得基於游標的排列簡單:
WHERE id > :last_id ORDER BY id LIMIT 50。 - 它仍然是一個標準 UUID:它適合已經接受 UUID 的原生
uuid列,ORM 和 API。 - 你可以從ID中提取建立時間進行除錯。
弱點
- 建立時間是任何看到ID的人都能看到的。對於大多數記錄來說,這是無害的;對於一些使用者來說,例如隱私敏感產品中的使用者帳戶,它可能會顯示某人何時註冊。
- 需要一個相當精確的鐘。大量的時鐘跳向後可以產生比現有的ID更早排序的ID;好的圖書館使用單調計數器來處理這一問題。
- 本源生成函式是較新的。PostgreSQL 18新增了
uuidv7();在舊版本中,生成應用程式程式碼。
ULID:可分類和緊的文字
ULID (普遍獨特的詞典解析識別器) 之前 UUID v7 使用相同的想法:48 位毫秒時間,其次是 80 個隨機位。區別在於文字形式:Crockford Base32的26個字元。
01J9Z3K8M2Q7X4V5B6N8P0R2T4
優勢
- 短於36個字元的 UUID 字串和 URL 安全。
- 字母大寫不敏感,不含含糊的字母 (I,L,O,U),因此更容易大聲閱讀或打字。
- 詞典學字串排序等於時間排序,這有助於儲存ID作為文字的系統,例如關鍵值儲存或日誌檔名。
弱點
- 它不是 UUID,因此它不適合沒有轉換的原生 UUID 列型別 (儘管其 128 位可以儲存在一箇中)。
- 一個社群規範而不是IETF標準,圖書館之間的行為略有不同。
- 像V7一樣,它暴露了創造時間。
一對一的比較
| 財產 | 其他 | 無線路標識號 | 標籤: |
|---|---|---|---|
| 尺寸 | 128位 | 128位 | 128位 |
| 文字長度 | 36 | 36 | 26 |
| 時間排序 | 沒有 | 是的 | 是的 |
| 洩露建立時間 | 沒有 | 是的 (ms) | 是的 (ms) |
| 標準 | 其他型別 | 其他型別 | 歐盟規範 |
| 本機DB型別 | uuid |
uuid |
通常是文字或二進位制 |
| 適合索引的外掛 | 窮人 | 很好 | 很好 |
儲存技巧
無論你選擇什麼,儲存ID為16位元組,而不是文字。一個36個字串佔用空間的兩倍以上,。PostgreSQL具有原生 uuid 型別;MySQL 使用者可以使用 BINARY(16) 與 UUID_TO_BIN(uuid, 1),第二個引數重新排序 v1 時間對於 v7 使用預設排序,因為它已經排序時間。
在APIs中以其正規文字形式展示ID。客戶應該把它們視為不透明的字串,
安全考慮
這些身份證都不是秘密。不要把它們當作密碼重置令牌或會話識別符號,。一個v4 UUID有足夠的隨機性無法測量,但v7和ULID具有可預測的時間前,可減少有效的。對於秘密,使用加密生成器生成至少128個隨機位,並將它們視為密碼,理想情況下只儲存一個雜湊。
另外還要考慮列舉。順序整數可以讓任何人猜到/orders/1001,/orders/1002。隨機或時間順序的ID使得這不切實際,但它們不能取代每一個請求的授權檢查。
你應該選擇哪一種?
- 新系統中的資料庫初級金鑰: UUID v7。您可以獲得分散式生成和良好的索引效能,
- 公共識別符號,建立時間必須保持私密: UUID v4,或 v7 內鍵結合單獨的隨機公共識別符號。
- 基於文字的儲存,檔名或ID,人們可以輸入: ULID,其較短,小寫不敏感的形式。
- **現有系統在v4上出現效能問題:**對於新表,考慮v7;在一個列中混合版本在技術上很好,因為兩者都是有效的 UUID。
生成識別符號
對於快速任務種子資料,測試裝置,手動插入基於瀏覽器的UUID生成器可以使用crypto.getRandomValues同時生成高達1,000個v4,v7或ULID值。在應用程式程式碼中,使用您語言的標準庫或維護良好的包,並儘可能接近建立記錄的ID。
總結
雖然 UUID v4 是隨機和私有,。UUID v7 新增了一個時間前,使插入快速,ID 可分類,同時保持標準 UUID。ULID提供了相同的排序方式,。對於大多數新應用程式來說,UUID v7 是最佳預設;當定時必須隱藏時,達到v4,當人類或基於文字的系統處理ID時,ULID。
本頁內容由英文自動翻譯而來,如發現錯誤,歡迎告訴我們。