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不同版本和顺序递增探究/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357