一句话回答
UUID(通用唯一标识符)是一个 128 位的值,通常写成 36 个字符,例如 3f2b8c1e-7d4a-4f6b-9a21-5c0e8d7b1f42。它可以在任何机器上独立生成,两个 UUID 相同的概率小到可以忽略。
公式: 128 位 = 32 个十六进制数字,按 8-4-4-4-12 分组
什么是 UUID?
UUID(通用唯一标识符)是一个 128 位的数字,用作 ID。任何系统都能自己生成,不用请求中央服务器,两个系统生成出同一个值的概率小到可以忽略。微软把同样的东西叫 GUID。
现行标准是 RFC 9562(2024 年 5 月),它取代了 RFC 4122,新增了 v6、v7、v8 三个版本。
格式
UUID 写成 32 个十六进制数字,分五组,加上连字符共 36 个字符:
3f2b8c1e-7d4a-4f6b-9a21-5c0e8d7b1f42
- 各组长度是 8-4-4-4-12。
- 第三组的首位是版本号(这里是
4)。 - 第四组的首位表示变体,标准 UUID 是 8、9、a 或 b。
各个版本
| 版本 | 由什么生成 | 适合场景 |
|---|---|---|
| v1 / v6 | 时间戳 + 节点(常是 MAC 地址) | 老系统;v6 是 v1 调整顺序后的可排序版本 |
| v3 / v5 | 对命名空间和名称做哈希(MD5 / SHA-1) | 同样的输入必须得到同样的 ID |
| v4 | 122 位随机数 | 需要一个随机的不重复键 |
| v7 | 毫秒级 Unix 时间 + 随机数 | 数据库主键,或希望 ID 按生成时间排序 |
v4 和 v7 怎么选:两者都能放心地在任何地方生成。v4 是随机的,写进数据库索引时位置分散,大表插入会变慢;v7 随时间递增,新行都追加在索引末尾。代价是 v7 会大致暴露生成时间。
碰撞的概率有多大?
v4 UUID 有 122 位随机数,约 5.3 × 10³⁶ 种取值。按生日界计算,要生成大约 2.7 × 10¹⁸ 个(270 亿亿个),任意两个相同的概率才到 50%。现实中的重复来自有缺陷的随机数生成器或被复制的 ID,而不是数学本身。
怎么生成
| 语言 | 代码 |
|---|---|
| JavaScript(浏览器、Node 19+) | crypto.randomUUID() |
| Python | import uuid; uuid.uuid4() |
| PostgreSQL 13+ | gen_random_uuid() |
| Go | github.com/google/uuid → uuid.New() |
| 命令行(macOS、Linux) | uuidgen |
上面这些生成的都是 v4。v7 的支持还在陆续跟上:PostgreSQL 18 新增了 uuidv7(),多数语言有现成的库。
UUID 在数据统计里的用处
- 事件去重。 给每个业务事件(一笔订单、一次注册)一个稳定的 ID,重试或者两边都上报时不会多出一行。
- 匿名 ID。 很多 SDK 会在设备上存一个随机 UUID,用来在多次会话之间认出这台设备。
- 关联数据。 在源头生成的 UUID 能把统计事件和你自己数据库里的记录对上。
在 TapCub 里,服务端事件可以带 insert_id 作为幂等键:同一个键再次到达、事件时间在 1 天之内,后到的那条会被丢掉,保留先到的。用 UUID 可以;但如果事件本身有天然的 ID(比如订单号),优先用它,这样浏览器和服务端会发同一个键。见发送服务端事件。另外,TapCub 网站脚本默认不写 Cookie,它的访客 ID 是加盐哈希,不是存下来的 UUID。
相关阅读
这个解释清楚吗?
我们会根据反馈修改和补充这篇内容。
提交没有成功,请稍后再试。
谢谢你的反馈,我们会据此改进这篇内容。你已经反馈过这篇了,谢谢。
