alltools.one
Development
2025-07-03
7 min
alltools.one Team
UUIDIdentifierDatabaseAPIDevelopment

UUID 指南:版本、格式與最佳實踐

UUID(通用唯一識別碼)是 128 位元的識別碼,設計目的是在無需中央管理機構的情況下,在空間和時間上保持唯一性。對於需要獨立產生 ID(無需協調)的分散式系統而言,UUID 是標準的首選方案。

UUID 格式

UUID 是一個 128 位元的數字,以 32 個十六進位數字呈現,分為五組並以連字號分隔:

550e8400-e29b-41d4-a716-446655440000
^^^^^^^^ ^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^
time-low  mid  hi   clk   node
               +ver  +var
  • 總計:128 位元(16 位元組)
  • 字串長度:36 個字元(32 個十六進位字元 + 4 個連字號)
  • 版本:編碼於第 13 個字元(「hi」半位元組)
  • 變體:編碼於第 17 個字元

使用我們的 UUID 產生器即可立即產生 UUID。

UUID 版本

UUID v1:基於時間

根據當前時間戳記和機器的 MAC 位址產生。

// 結構:時間戳記(60 位元)+ 時鐘序列(14 位元)+ 節點(48 位元)
6ba7b810-9dad-11d1-80b4-00c04fd430c8

優點:可按建立時間自然排序,每台機器保證唯一性。 缺點:會暴露 MAC 位址(隱私疑慮),可能洩漏建立時間。 適用時機:需要時間排序且處於受控環境時。

UUID v4:隨機

由密碼學安全的隨機數產生。這是最廣泛使用的版本。

// 122 個隨機位元(6 個位元保留給版本和變體)
f47ac10b-58cc-4372-a567-0e02b2c3d479

優點:簡單、不洩漏資訊、無需協調。 缺點:無法排序,資料庫索引效能略遜於序列 ID。 適用時機:通用場景——這是大多數應用程式的預設選擇。

UUID v7:時間排序隨機(新標準)

最新版本(RFC 9562,2024),結合 Unix 時間戳記與隨機資料。

// 結構:時間戳記(48 位元)+ 隨機(74 位元)
018e7b50-4a00-7000-8000-000000000001

優點:自然按時間排序、優秀的資料庫索引效能、除毫秒精度外不洩漏資訊。 缺點:較新,部分函式庫可能尚未支援。 適用時機:需要按時間順序排列的唯一 ID——非常適合作為資料庫主鍵。

其他版本

  • UUID v3:基於命名空間和名稱的 MD5 雜湊。具確定性。
  • UUID v5:基於命名空間和名稱的 SHA-1 雜湊。具確定性,優先於 v3 使用。
  • UUID v6:重新排列的 v1,提升排序能力。已被 v7 取代。
  • Nil UUID:全零(00000000-0000-0000-0000-000000000000)。用作哨兵值。

碰撞機率

隨機產生的 UUID(v4)碰撞的可能性有多大?以 122 個隨機位元計算:

  • 產生 10 億個 UUID 後:機率約為 10^18 分之 1
  • 要達到 50% 的碰撞機率:需要大約 2.7 × 10^18 個 UUID
  • 以每秒 10 億個 UUID 的速度:大約需要 86 年

就所有實際用途而言,UUID v4 碰撞不會發生。你遇到硬體故障的機率遠高於碰撞。

UUID 與其他 ID 格式比較

格式長度可排序唯一URL 安全
UUID v436 字元
UUID v736 字元
ULID26 字元
nanoid21 字元大致是
自動遞增不定單表內
Snowflake ID18-19 字元單系統內

ULID(通用唯一字典排序識別碼)

ULID 是一種精簡的替代方案:48 位元時間戳記 + 80 位元隨機數,編碼為 26 個 Crockford Base32 字元。它們可按建立時間進行字典序排序。

何時使用自動遞增 ID

對於單一資料庫應用程式,序列 ID 更簡單且更高效。在以下情況下使用 UUID:

  • ID 由多個系統獨立產生
  • 不希望向外部使用者暴露插入順序
  • 需要適合分散式資料庫合併的 ID

資料庫效能考量

隨機 UUID(v4)會導致 B-tree 索引碎片化,因為插入發生在隨機位置。在大型資料表上,這可能使寫入效能下降 2-5 倍。

解決方案

  1. 使用 UUID v7:時間排序的 UUID 按順序插入,效能與自動遞增相當
  2. 以二進位儲存:使用 BINARY(16) 取代 CHAR(36) 可節省 55% 儲存空間
  3. 使用 ULID:可排序且比 UUID 更精簡
-- PostgreSQL:原生 UUID 類型(16 位元組,高效)
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL
);

-- MySQL:以 BINARY(16) 儲存以提升效能
CREATE TABLE users (
  id BINARY(16) PRIMARY KEY,
  name VARCHAR(255) NOT NULL
);

產生 UUID

命令列

# macOS/Linux
uuidgen

# Python 單行指令
python3 -c "import uuid; print(uuid.uuid4())"

JavaScript

// 內建方法(Node.js 19+、現代瀏覽器)
crypto.randomUUID();

// UUID v7(使用 uuid 套件)
import { v7 } from 'uuid';
const id = v7();

Python

import uuid
uuid.uuid4()  # Random
uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')  # Name-based

如需快速產生 UUID 而不需撰寫程式碼,我們的 UUID 產生器可在瀏覽器中即時建立 v4 UUID。

常見問題

資料庫主鍵應該使用 UUID 還是自動遞增整數?

對於單一資料庫應用程式,自動遞增整數更簡單且更快速。對於分散式系統、微服務,或者需要在資料庫插入前於客戶端產生 ID 的情況,UUID(最好是 v7)是更好的選擇。如果你使用 PostgreSQL,原生 UUID 支援使得效能差異可以忽略不計。

UUID 可以用作安全令牌嗎?

UUID v4 使用來自密碼學來源的 122 位元隨機數,提供良好的熵值。然而,對於安全令牌(API 金鑰、Session ID),最好使用專門設計的令牌格式,這些格式具有額外的屬性,如校驗碼、過期時間編碼或前綴識別。UUID 的用途是身分識別,而非驗證。

相關資源

Published on 2025-07-03
UUID Guide: Versions, Formats, and Best Practices | alltools.one