Command Palette

Search for a command to run...

UUID 產生器:v1、v4、v7 已解釋(以及實際使用)

UUID 產生器:v1、v4、v7 已解釋(以及實際使用)

T
Toolz Team
|Jul 1, 2026|16 閱讀

雜項工具 合集的一部分

第一次 UUID 對我來說真正重要時,我正在將 WordPress 相鄰的 SaaS 從單一 MySQL 框移動到具有讀取副本的設置,併計劃稍後進行分片。自動增量 ID 多年來一直很好 - 直到兩個服務開始插入到將成為相同邏輯表的內容中,然後突然 id = 42 意味著兩行不同的行。那'自動增量悄悄停止工作的那一刻,UUID 是通常的答案。

UUID 是一個 128 位元值,您可以隨時在任何機器上生成,無需協調,並且仍然相信它是唯一的。那個&引用;沒有協調&引用;部分是重點:平面上離線的行動應用程式、三個微服務和一個後台工作人員都可以同時發送 ID,並且永遠不會衝突。支持這種信心的數學支持確實是荒謬的,I'稍後會向您展示這是多麼荒謬。

uuid 生成器 在 toolz。dev 上,立即在瀏覽器中建立多個版本的單一或批次 UUID - 當您&#39 時很方便;重新播種表格或需要一次性 ID 進行測試。本指南涵蓋了版本的實際含義、2026 年選擇哪個版本、如何在不破壞資料庫索引的情況下儲存它們,以及我犯的錯誤,以便您可以跳過它們。

TL;DR: 對於 2026 年新的資料庫主鍵,產生 UUID v7- it' 是按時間順序排列的,因此索引良好,但它不會'洩漏像 v1 這樣的硬體。使用 v4 當你想要純粹的不可預測性時。將它們儲存為本機 uuid 類型或 BINARY(16),從來沒有 VARCHAR(36). 將它們批量製作 uuid 生成器,並將其與配對 時間戳轉換器 閱讀 v7 中烘烤的時間。所有客戶端,全部免費。


什麼是 UUID,確切地說?

UUID(通用唯一識別碼)是一個 128 位元數字,用於識別某些內容,而無需中央機構分發 ID。微軟將同一件事稱為 GUID(全球唯一識別碼);他們'在各方面都相同。規範文字形式為 36 個字元 - 32 個十六進位數字,分為 5 個 8-4-4-4-12 的連字符組:

550e8400-e29b-41d4-a716-446655440000

其中兩個十六進位位置是 't 隨機資料 - 它們're 元資料。第 13 個十六進位數字編碼 版本 (由哪一代策略組成),第四組的第一位數字編碼 變體 (它遵循哪種佈局標準 - 8, 9, a,或者 b 對於標準 UUID)。所以在上面的例子中, 4 在第三組中告訴你'是v4。

"unique,"有多獨特?真的嗎?

保留版本和變體位元後,v4 UUID 有 122 個隨機位元。 That's 2^122 個可能的值,或大約 5.3 十億:

5,316,911,983,139,663,491,615,228,241,121,400,000

要具體化:如果你每秒產生 10 億個 UUID,你'大約需要 86 年才能達到 50% 的機會 單身的 任何地方的碰撞。在實際工程術語中,v4 碰撞不會發生,您可以像永遠不會發生一樣進行設計。


什麼'是 UUID v1、v4 和 v7 之間的差異?

規範 - 最初 RFC 4122,現已更新 RFC 9562 (2024)- 定義多個版本。日常工作需要三件事。

UUID v1 - 時間戳 + MAC 位址

v1 使用網路卡和#39;s MAC 位址拼接一個 100 奈秒的時間戳(從 1582 年 10 月 15 日開始計算,公曆開始日期 - 我最喜歡的規格瑣事之一)。 It's 自然按時間順序排列,您可以從中提取創建時間。

問題就在於定義:它嵌入了製造它的機器的 MAC 位址。這會洩漏硬體身份,並與時間戳結合,使 ID 有點可預測。例子: 6ba7b810-9dad-11d1-80b4-00c04fd430c8. I'd 現在僅使用 v1 進行舊版相容性。

UUID v4 - 隨機

v4 是 122 位元隨機性,僅此而已。它'這是大多數人說"UUID,"時所指的版本。它'非常簡單:沒有時間戳,沒有硬件,沒有訂單。例子: f47ac10b-58cc-4372-a567-0e02b2c3d479.

好處是它不會洩漏任何東西並且不可預測,這正是您想要的應該'不可猜測的任何東西。缺點是它's 隨機的因此,連續的插入分散在您的索引中 - 正如我發現的那樣,這在規模上具有真正的性能成本。

UUID v7 - 時間排序 + 隨機

v7 是現代折衷方案,在 RFC 9562 中標準化。前 48 位元是以毫秒為單位的 Unix 時間戳記;其餘的都是隨機的。例子: 018e4880-d4d0-7b9c-8c37-2a5c0f1e3d8a.

這種佈局意味著 v7 ID 按時間順序排序 - 新行落在 "end" B 樹索引而不是分散 - 同時仍然是全域唯一且無協調的。它洩漏了大約創建時間(通常很好),但沒有洩漏硬體。對於新項目,這是我的預設主鍵,它'IETF 現在也指向的方向。

這裡'一目了然的權衡:

版本 訂購了? 洩漏 最好
v1 是的(時間) MAC位址+時間 僅舊系統
v4 不(隨機) 沒什麼 不可猜測的代幣,一般 ID
v7 是的(時間) 大約創建時間 新的資料庫主鍵

也存在較少使用的版本:v3 和v5 是命名空間加名稱的確定性雜湊(v5 使用SHA-1,並且優於v3 和#39;MD5),v6 是重新排序的v1,v8 保留用於自訂實作。


您應該使用 UUID 或自動增量 ID 嗎?

這是辯論 I'我的設計評論比其他任何評論都多,所以這裡'是我實際使用的框架而不是宗教答案。

堅持自動增量時 你有一個資料庫,效能和儲存空間都很緊張,人類需要讀取ID。整數是 4 個 8 位元組與 UUID&#39 相比; s 16,整數比較更快,並且 "訂單#12345"與 36 個字元的 UUID 相比,透過手機閱讀要容易得多。在一個沒有分片的盒子裡,自動增量確實是更簡單、更快的選擇 - don't 達到過時的 UUID。

切換到 UUID 時 其中任何一個都是正確的:you're 分散式(多個服務或伺服器獨立鑄造 ID),you'擔心枚舉(自動增量 ID 是可以猜測的,並悄悄地顯示您的記錄計數 - /users/1234 告訴攻擊者您的使用者少於 1,235 個),您需要合併多個資料庫中的資料而不發生衝突,或者您希望客戶端在同步之前產生 ID。這個枚舉點是人們低估的真正安全考量。

還有v7中間立場: UUID v7 為您提供分散式 UUID 產生 自動增量的指數友善排序,無需洩漏記錄計數。對於 2026 年大多數需要非順序 ID 的新項目,v7 是結束爭論的答案。


如何在不破壞索引的情況下儲存 UUID?

這是我自己代價高昂的錯誤所生的部分,所以如果其他地方沒有的話,請注意這裡。

在我提到的遷移中,我將新的 UUID 儲存為 VARCHAR(36) 因為這是顯而易見的、可讀的事情。它起作用了 - 然後表格變大,插入和連接明顯變慢。兩個問題變得更加複雜:我每個 ID 花了 36 個位元組,而不是 16 個位元組 我使用隨機 v4 UUID,因此每個插入都落在主鍵索引中的隨機位置,將其分割並抖動緩衝池。修復方法是將它們儲存為二進位,並在下一個專案中切換到 v7,以便插入保持順序。

PostgreSQL 有本地人 uuid 類型 - 使用它。它儲存 16 個位元組並快速比較:

CREATE EXTENSION IF NOT EXISTS "pgcrypto";

CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
);

我的SQL 沒有本機 UUID 類型,因此儲存 BINARY(16) 並轉換為 UUID_TO_BIN() / BIN_TO_UUID(). 第二個論點很重要:

CREATE TABLE users (
    id BINARY(16) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- The `true` swaps the timestamp bytes for better index locality on v1
INSERT INTO users (id, name, email)
VALUES (UUID_TO_BIN(UUID(), true), 'Alice', '[email protected]');

SELECT BIN_TO_UUID(id, true) AS id, name, email FROM users;

要記住的規則:本地 uuid 輸入您擁有的地方, BINARY(16) 你在哪裡't,和 VARCHAR(36) 基本上永遠不要輸入 you'll 索引並加入。


如何在程式碼中產生 UUID?

為了快速一次性, uuid 生成器 比打開 REPL 快。在程式碼中,每種主要語言都內建或遠離此功能。

JavaScript/TypeScript- 瀏覽器和節點現在都附帶一個 v4 產生器:

const id = crypto.randomUUID();   // v4, no dependency needed
// For v7, use the 'uuid' package:
import { v7 as uuidv7 } from 'uuid';
const ordered = uuidv7();

蟒蛇:

import uuid
uuid.uuid4()                                  # random
uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com') # deterministic (SHA-1)

爪哇: UUID.randomUUID() 開箱即用,為您提供 v4; v7 需要一個類似的庫 java-uuid-generator 或小型 RFC 9562 實作。

去: github.com/google/uuid 給你兩個 - uuid.New() 對於v4和 uuid.NewV7() 對於v7。

請注意,本機執行時間助手幾乎總是為您提供 v4。如果您特別想要 v7 進行訂購,您通常需要一個庫,因為它'較新的標準,但並非每個標準都趕上了。


UUID 在真實系統中實際顯示在哪裡?

它'很容易抽像地談論 UUID,所以這是 I' 的具體位置;我依賴它們,因為你選擇的版本確實取決於工作。

分散式設定中的資料庫主鍵。 這是經典案例,也是本文的開頭案例。當多個作者可以插入同一個邏輯表(副本、碎片或共享模式的兩個服務)時,自動增量中斷。 v7 主鍵解決了協調問題,並且仍然可以乾淨地索引,因為它's 按時間順序排列。

客戶端為離線優先應用程式產生的 ID。 行動應用程式或瀏覽器 SPA 通常需要建立記錄才能與伺服器通話 - 想想寫在平面上的註釋,或立即顯示新行的樂觀 UI。如果客戶端預先發出 UUID,則記錄從第一次按鍵開始就具有穩定的身份,並且稍後無需伺服器往返即可同步到 "取得 ID。" I'即使在不穩定的連接下,也用它來讓表單感覺即時。

URL 和 API 中的不可枚舉資源識別碼。 推桿 /orders/1042 在 URL 中悄悄地告訴任何人您'最多有 1,042 個訂單,並讓他們走路 /orders/1041, /orders/1040,等等。交換 UUID 可以消除業務指標洩漏和簡單的枚舉。對於使用者在 URL 中看到的任何內容,這都值得做 - 但請記住,UUID 不是存取控制機制;您仍然需要其背後的真正授權檢查。

用於追蹤的相關 ID。 當單一請求在五個微服務中扇出時,將一個 UUID 作為關聯 ID 附加並在每次跳躍時記錄它 "在這個混亂的某個地方,有些東西失敗了"變成一個跨越所有日誌的可抓取字串。這是一個即使是普通 v4 也很完美的地方 - 您不需要'不需要排序,只需要唯一性。

冪等鍵。 支付和網路掛鉤 API 通常要求客戶端發送 UUID 作為冪等金鑰,以便重試的請求不會'向卡片充電兩次。客戶端產生一次,重試時重複使用,伺服器對其進行重複資料刪除。 It'這是一個小模式,可以防止非常昂貴的錯誤類別。


常見問題

UUID 有何用途?

UUID 唯一地識別某些內容 - 資料庫行、API 資源、會話、上傳的檔案、跨微服務的追蹤 - 無需中央服務即可分發 ID。它'每當多個系統或客戶端必須獨立建立識別碼並且仍然確保它們獲勝時,它就會成為首選't 衝突。您可以立即產生一個 uuid 生成器 在 toolz。dev 上。

兩個 UUID 可以相同嗎?

理論上是的;實際上不是。 v4 UUID 有 122 個隨機位,提供約 5.3 十億種可能性。你'在達到 50% 的偶數碰撞幾率之前,需要產生大約 2.7 quintillion UUID。對於每個真正的工程目的,您可以將 UUID 視為保證唯一。

2026 年我應該使用哪個 UUID 版本?

對於新的資料庫主鍵,UUID v7 - it'按時間順序排列,以實現高效索引,同時保持全域唯一性,並且 ' RFC 9562 下的目前 IETF 建議。當不可預測性很重要時,例如不可猜測的標識符,請使用 v4。避免 v1 進行新工作,因為它嵌入了生成機和#39;s MAC 位址。

UUID 是連續的嗎?

v1 和 v7 是按時間順序排列的,因此稍後產生的 ID 會先排序後排序; v4 是完全隨機的,沒有順序。順序排序使 v7 對 B 樹索引友好 - 新行附加而不是分散。如果您'使用隨機 v4 作為大表上的主鍵,則缺乏順序可能會損害插入和索引效能。

如何將 UUID 儲存在資料庫中?

使用本機 uuid 如果您的資料庫有一個(postgresql 有),請鍵入。否則儲存 BINARY(16),並在 MySQL 8.0+ 中轉換為 UUID_TO_BIN()BIN_TO_UUID(). 避免 VARCHAR(36) 或者 CHAR(36) 對於按鍵 - 字串儲存每行浪費 20 個位元組並減慢每次比較的速度,這在大表上加起來很快。

什麼' UUID 和 GUID 之間的差異?

他們'是一樣的。 UUID 是 RFC 4122 中的術語,用於大多數語言和平台; GUID 是 Microsoft'它的名稱,在 Windows 和。NET 中很常見。格式和保證相同,因此您可以互換對待 GUID 和 UUID。

我可以從 UUID 中提取建立時間嗎?

從 v1、v6 和 v7 開始,是的 - 它們對時間戳進行編碼。 v7 在其前 48 位元中儲存毫秒 Unix 時間戳,您可以對其進行解碼和讀取 時間戳轉換器. v4 和 v5 不包含時間訊息,因此#39;沒有什麼可以從中提取的。

UUID v4 對於會話令牌來說足夠安全嗎?

不是靠它自己的。 v4' 122 個隨機位元是不可預測的,但會話和身份驗證令牌通常需要來自加密安全產生器的至少 256 位元。使用專門建構的安全隨機令牌進行驗證,並保留 UUID 來識別資源而不是保護資源。

如何產生 UUID?

使用您的語言's 內建產生器: crypto.randomUUID() 在現代瀏覽器和 Node。js 中, uuid.uuid4() 在python中,或者 Guid.NewGuid() 在。NET 中,每個呼叫都會產生一個 v4 UUID。對於快速一次性或批次,請立即使用 產生它們 uuid 生成器 在 toolz。dev 上 - 無需程式碼。

UUID 有多少個字元?

UUID 的規範文字形式為 36 個字元:32 個十六進位數字加上將其分成 8-4-4-4-12 組的四個連字符。該文字編碼 128 位,這就是為什麼將其儲存為 16 個原始位元組 BINARY(16) 比 36 個字元的字串緊湊得多。


包裹起來

UUID 是您所擁有的基礎之一'不要考慮,直到系統發展超過單一資料庫 - 然後它們'就是一切。 2026 簡短版本:預設為 v7 對於新的主鍵,請使用 v4 當您需要無法猜測的 ID 時,請將它們儲存為 本土的 uuid 或者 BINARY(16),並跳過 v1 以獲取任何新內容。向我的學習 VARCHAR(36) 下午所以你不要'重複它。

使用免費立即產生它們 uuid 生成器 在 toolz。dev 上 - 單一或批量、任何版本、所有客戶端,未上傳任何內容。當您需要讀取 v7 內部的時間時,請聯絡 時間戳轉換器,並瀏覽其餘的內容 編碼工具- 600 多個免費公用事業 - 超過 工具。dev.

Frequently Asked Questions

A UUID uniquely identifies something — a database row, an API resource, a session, an uploaded file, a trace across microservices — without needing a central service to hand out IDs. It's the go-to whenever multiple systems or clients must create identifiers independently and still be sure they won't clash. You can generate one instantly with the UUID Generator on toolz.dev.

Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!