做后端的没人没碰过UUID,数据库主键、分布式ID、会话token到处都是它那串连字符的字符串。但真问起来v1和v4差在哪、会不会重复、为啥有的版本带MAC地址,能答全的不多。下面把常被问到的几个问题一次讲清。
【UUID到底是什么?】UUID全称通用唯一识别码,是一个128位也就是16字节的标识符,通常写成32个十六进制字符加分五段的格式,形如550e8400-e29b-41d4-a716-446655440000。前面是8位,中间三段各4位,倒数第三段4位,最后一段12位,中间用连字符隔开。128位意味着可能的取值有2的128次方,这是个天文数字,所以它能在不中心协调的情况下保证基本不重复。
【v1和v4有什么区别?】v1是基于时间戳加MAC地址生成的,它把当前时间精确到100纳秒级的时间戳、一个时钟序列和网卡的MAC地址拼进UUID里,所以v1是时序可追溯的,按生成时间能排序,但缺点是暴露了生成机器的MAC地址,有隐私问题。v4是用随机数生成的,除了版本位和变体位是固定的,其余122位全随机,不可排序、不带机器信息,隐私友好,这也是现在最常用的版本。
【v2、v3、v5又是什么?】v2是DCE安全版本,基于v1加了个本地标识符,实际很少用。v3和v5是基于命名空间加名字的哈希生成,区别在哈希算法:v3用MD5,v5用SHA-1。流程是先有个固定的命名空间UUID,再把你要标识的名字和命名空间拼起来做哈希,截前16字节当UUID。好处是同样的命名空间加同样的名字永远生成同样的UUID,适合需要确定性映射的场景,比如把URL或域名映射成固定ID。因为SHA-1比MD5更安全,新项目建议用v5而不是v3。
【v4真的不会重复吗?】理论上会,但概率极小。v4有122位随机性,生成两个相同UUID的概率是2的负122次方。形象点说,如果你每秒生成十亿个UUID,连续生成约85年,重复概率才约百分之五十。所以工程上把v4当唯一用没问题。真正要担心的不是算法碰撞,是随机数源质量不行或种子重复导致的伪碰撞。
【为什么有的UUID带MAC地址?】那是v1。v1把48位MAC地址放在UUID末尾12位里,能识别生成节点。好处是分布式生成时不冲突,坏处是隐私泄露,机器网卡一换UUID特征就变,还能被追踪。所以浏览器、操作系统这些面向用户的场景都禁用v1改用v4或v7。
【UUID v7是什么?】较新的标准还加了v6和v7。v7是把时间戳放在最高位、后面接随机数,既保持了时序可排序又不用MAC地址,解决了v4不能排序和v1泄露隐私的问题,适合做数据库主键和日志ID这种需要按时间递增的场景,是未来趋势。还有v8给自定义方案留口子。
【UUID做数据库主键好不好?】能用,但有取舍。128位比自增整数占空间,索引也更慢,因为B+树插入是随机的会频繁页分裂。v4随机插入尤其伤写性能。如果写入量大,可以考虑v7或雪花算法这种时序ID,或者自增主键加UUID做业务标识分开存。小项目无所谓,量大时这个设计差异很明显。
【GUID和UUID是一回事吗?】基本是。GUID是微软的叫法,UUID是标准叫法,格式都是128位。细微差别是GUID有时混合大小写、某些实现字节序不同,跨平台传时偶尔要对齐字节序,但绝大多数情况下当一个东西用。
UUID这东西核心记住:v4最通用够安全,v7是趋势适合主键,v1有隐私问题尽量别用。选对版本比纠结碰撞概率重要得多。