一句话定义:UUID(Universally Unique Identifier,通用唯一识别码)是一个 128 位的标识符,通常写成 32 个十六进制字符加 4 个连字符,例如 3f2b9c1e-...。它的设计目标不是“短”或“好读”,而是在没有任何中央机构协调的前提下,让互相不通信的机器各自生成,也几乎不会撞车。
打个比方:自增 ID 像银行网点的叫号机——只有一台机器发号,所有人都得排队问它要。单机时代没问题,可一旦业务拆成几十个微服务、几十个数据库分片,这台“叫号机”放哪儿?跨机房调用要扛延迟,它一宕机全站写不进去。UUID 则是让每个人自己掷骰子:随机空间有 2^128 那么大,两台从未通信的机器同时生成同一个号的概率低到可以忽略不计(具体的碰撞概率推导以官方规范为准)。
为什么分布式系统躲开自增 ID:自增 ID 短、连续,对 B+ 树索引非常友好,这是它至今仍是单库主键首选的原因。但它有三个严重缺点:需要单点发号;分库分表后各表 ID 会重复;连续整数会泄露业务量——今天订单号是 1001,明天是 2001,外人一眼就能看出你的增长速度。
为什么 UUID 又不能拿来排序:v4 的 122 位全是随机数,完全没有顺序。把它当主键插进数据库的聚簇索引(clustered index)时,每次插入位置都落在 B+ 树中间的不同页上,频繁页分裂、缓存命中率下降、写放大严重。所以准确地说,是“随机写慢”,不能只说“UUID 慢”;换成同样随机的数字主键,也一样慢。
v4 和 v7 差在哪:v4 纯随机,适合做请求 ID、幂等键、对象存储文件名这类“只要唯一、不管顺序”的场景。v7 是较新标准引入的版本,前 48 位放毫秒级时间戳,后面才是随机位——既保留无协调生成,又具备“按时间大致有序”的性质,插入索引时基本是追加写。代价是它暴露了生成时间(v1 则更糟,曾把网卡 MAC 地址编进去)。
| 对比项 | 自增 ID | UUID v4 | UUID v7 |
|---|---|---|---|
| 是否需要中心协调 | 需要 | 不需要 | 不需要 |
| 有无顺序 | 严格递增 | 随机 | 按时间大致有序 |
| 索引写入表现 | 好 | 差(随机写) | 较好(近似追加) |
| 会否泄露信息 | 泄露业务量 | 基本不泄露 | 泄露生成时间 |
| 典型用途 | 单库主键 | 请求 ID、文件名 | 分布式主键 |
对从业者的意义:主键选型要先看“有没有中心发号能力”和“写入是否密集”。单库小表用自增最省事;跨库跨服务、写入量大的场景,UUID v7 或雪花算法这类“时间前缀 + 随机/机器位”的方案通常更划算。另外提醒一句:UUID 是“唯一”,不等于“不可猜”,别把 v4 直接当访问令牌用,那属于另一个安全问题,需要密码学安全的随机源,具体以官方文档为准。
对普通人的意义:你在订单号、退款单号、文件分享链接里看到的那串 36 位乱码,多半就是它——它不是为了让你念出来,而是为了让全世界互不相识的服务器,不用开会也能各自编号。
