UUID(GUID)不同版本和順序遞增探究


概念

UUIDs (Universally Unique IDentifier),也稱為 GUIDs (Globally 唯一標識符)。一個 UUID 是 128 位長,並且可以保證空間和時間上的唯一性。

使用 UUID 的主要原因之一是無需集中的管理,並且 UUID 的生成算法要求它支持單台每秒超過百萬次的生成速率。

布局和字節順序

UUID 呈現的格式為:f81d4fae-7dec-11d0-a765-00a0c91e6bf6

字段 數據類型 字節 注釋
time_low unsigned 32 bit integer 0-3 低域位整數時間戳
time_mid unsigned 16 bit integer 4-5 中間字段位整數時間戳
time_hi_and_version unsigned 16 bit integer 6-7 高場位整數時間戳
clock_seq_hi_and_reserved unsigned 8 bit integer 8 整數時鍾序列與多路復用
clock_seq_low unsigned 8 bit integer 9 低域位整數時鍾序列
node unsigned 48 bit integer 10-15 空間唯一位整數節點標識符

版本

版本號在時間戳的最高 4 位(time_hi_and_version 的 4-7 bit)

UUID 的變體規則如下

Msb0 Msb1 Msb2 Msb3 版本 描述
0 0 0 1 v1 基於時間的版本
0 0 1 0 v2 DEC 安全版本
0 0 1 1 v3 基於名稱的版本(本文件中規定使用 MD5 散列)
0 1 0 0 v4 隨機或偽隨機生成的版本
0 1 0 1 v5 基於名稱的版本(本文件中規定使用 SHA-1 散列)

版本更准確地說應該叫子類型,稱其為版本只是為了兼容性。

時間戳

時間戳是一個 60 位的值,一般使用 UTC 時間表示,如果沒有 UTC 時間可用本地時間,但是盡量不建議這樣做,因為本地時間要生成 UTC 時間需要額外的時區信息。

時間序列

時間序列用於幫助避免當時鍾向后設置時可能出現的重復或者節點 ID 改變。如果已知時鍾序列的先前值,則它智能遞增,否則它應該設置為隨機或者高質量的偽隨機值。類似地,如果節點 ID 發生變化(例如,因為網卡在機器間移動),需要重新設置時間序列。

對於 UUID 的版本 3 或 5,時鍾序列是 14 位根據名稱描述構造的值。

對於 UUID 的版本 4,時鍾序列是隨機或偽隨機的 14 位值。

節點

對於 UUID 的版本 1,節點字段包含一個 IEEE 802 MAC 地址,通常是主機地址。

對於 UUID 的版本 3 或 5,節點字段是 48 位根據名稱描述構造的值。

對於 UUID 的版本 4,節點字段是隨機或偽隨機生成 48 位值。

nil UUID

nil UUID 是 UUID 的特殊形式,是所有 128 位均設置為零。

順序 UUID

在數據庫中存儲,經常使用 UUID 作為主鍵,但是 UUID 有個致命缺陷,就是沒有順序。如果這種無順序的 ID 當作主鍵在數據庫中使用會嚴重影響數據庫的性能。

現在有很多框架使用的算法支持生成遞增的 UUID,例如 ABP 框架里的順序 ID 參考了 https://github.com/jhtodd/SequentialGuid/blob/master/SequentialGuid/Classes/SequentialGuid.cs,這個順序 ID 有個生成類型枚舉 SequentialGuidType,SQL Server 使用 SequentialAtEnd 類型,因為 SQL Server 使用最低的有效 6 個字節來排序,其他大多數數據庫應該傳遞 SequentialAsStringSequentialAsBinary

UUID v1 也定義了基於時間的版本,但是該標准將時間戳拆分為幾塊,限制了其作為順序 ID 的用途。因此這種順序 UUID 與傳統的 UUID 標准不兼容。

這個算法使用了 6 個字節 48 bit 來表示時間戳,精確到毫秒,大概能使用 5900 年,對於一般的應用足夠了。

還有一個時間精度更高的實現方案:https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/ebe011a6f1b2a2a9709fe558cfc7ed3215b55c37/src/EFCore.MySql/ValueGeneration/Internal/MySqlSequentialGuidValueGenerator.cs,時間戳占 8 字節,精度到 100 ns,但是這個實現里有一些位移操作符,還結合了 UUID 的變體版本號,沒有細看,猜測思路應該跟第一種順序 UUID 也類似。

參考

https://www.ietf.org/rfc/rfc4122.txt

原文地址:https://frhello.com/uuidguid不同版本和順序遞增探究/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM