UUID (Universally Unique Identifier) / GUID (Globally Unique Identifier)啥意思
UUID / GUID 的核心含义
这两个术语本质上指的是同一种东西——一个128位(16字节)的全局唯一标识符,只是命名规范不同:
术语 | 全称 | 来源 | 使用场景 |
UUID | Universally Unique Identifier | 开放软件基金会(OSF)标准化 | Linux、Java、Python、PostgreSQL 等开源生态 |
GUID | Globally Unique Identifier | 微软公司 | Windows、SQL Server、Office、COM组件等微软生态 |
一句话总结:UUID 和 GUID 是同一标准的不同叫法,微软叫 GUID,其他人叫 UUID,它们在技术实现上高度兼容。
🔍 从词源角度理解
Universally Unique(全球唯一)
Universe(宇宙)+ -ally(副词后缀)= 在宇宙范围内都唯一
虽然"宇宙"有点夸张,但确实表达了跨系统、跨网络、跨时空都不会重复的设计目标
Globally Unique(全局唯一)
Global(全球)+ -ly(副词后缀)= 在全球范围内都唯一
相比"宇宙","全球"更务实,强调不同组织、不同系统之间不会冲突
Identifier(标识符)
来自拉丁语
identificare(识别、认定)就是用来给某个东西贴标签的字符串
📋 长什么样子?
一个典型的 UUID/GUID 长这样:
text
6F9619FF-8B86-D011-B42D-00C04FC964FF
格式解析:
text
6F9619FF-8B86-D011-B42D-00C04FC964FF ├─32个十六进制数字(0-9, A-F) ├─用连字符分成5段 └─总长度:36个字符(32个数字 + 4个连字符) 时间低位(8) - 时间中位(4) - 时间高位+版本(4) - 变体+时钟序列(4) - 节点ID(12)
存储大小:16字节 = 128位
🎲 为什么能保证"唯一"?
UUID 的生成算法设计得非常巧妙,它结合了不重复的信息源:
版本1(基于时间+MAC地址)
text
UUID = 时间戳(100纳秒级) + 机器MAC地址 + 时钟序列
时间戳:从1582年开始,每100纳秒递增,确保不同时间的ID不重复
MAC地址:每台电脑网卡的物理地址全球唯一,确保不同机器的ID不重复
时钟序列:同一台机器同一时刻若生成多个ID,这个序列会递增
结果:理论上,你需要每秒生成10亿个UUID,持续约100年,才有1%的概率遇到重复。
版本4(完全随机)
text
UUID = 122位随机数 + 6位固定版本标识
使用密码学安全的随机数生成器
重复概率极低(约
1 / 2^122,几乎为零)
💡 为什么需要 UUID?
场景对比:自增ID vs UUID
| 特性 | 自增ID(1, 2, 3...) | UUID |
|---|---|---|
| 唯一性范围 | 仅限单表 | 跨系统、跨数据库、跨世纪 |
| 生成方式 | 数据库中心化生成 | 任何地方都可以独立生成 |
| 可猜测性 | 容易猜(下一个是N+1) | 完全随机,无法猜测 |
| 存储空间 | 4-8字节 | 16字节 |
| 人类可读 | ✅ 简单易懂 | ❌ 一串乱码 |
典型应用场景
分布式系统:多个服务器同时生成ID,无需协调就能保证不冲突
javascript
北京服务器生成:6F9619FF-8B86-D011-B42D-00C04FC964FF 纽约服务器生成:A1B2C3D4-E5F6-7890-AB12-CD34EF567890// 永远不会重复!
数据库主键:避免合并数据时的ID冲突
sql
-- 公司A的订单表INSERT INTO orders VALUES ('6F9619FF-...', '商品A');-- 公司B的订单表(收购后合并)INSERT INTO orders VALUES ('A1B2C3D4-...', '商品B');-- 两条记录的ID不会冲突!会话标识:Web应用的Session ID、JWT的JTI
文件名去重:上传文件时生成唯一文件名,避免覆盖
事件追踪:日志、消息队列中的消息ID
🔄 SQL Server 中的 UUID 函数
SQL Server 提供了两个函数:
函数 | 说明 | 示例输出 |
NEWID() | 生成随机的UUID(版本4) | 6F9619FF-8B86-D011-B42D-00C04FC964FF |
NEWSEQUENTIALID() | 生成递增的UUID(类似版本1) | 6F9619FF-8B86-D011-B42D-000000000001 |
使用示例:
sql
-- 创建表时使用UUID作为主键CREATE TABLE users (
user_id UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
user_name VARCHAR(50));-- 插入数据时自动生成UUIDINSERT INTO users (user_name) VALUES ('张三');-- user_id 自动变成类似 'A1B2C3D4-...'-- 手动生成UUIDSELECT NEWID(); -- 输出:6F9619FF-8B86-D011-B42D-00C04FC964FFNEWSEQUENTIALID() 的优势:
生成的UUID是递增的,可以避免B+树索引频繁分裂
性能比
NEWID()好(在作为主键时)
🎭 冷知识:UUID 的版本标识
UUID 字符串中的第15个字符(版本号)告诉你它是怎么生成的:
text
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx ↑ 这个 '4' 表示版本4(随机UUID)
| 版本 | 生成方式 | 使用场景 |
|---|---|---|
| 版本1 | 时间戳 + MAC地址 | 分布式系统,需要时间排序 |
| 版本3 | MD5哈希(名字空间+名称) | 根据名称确定性生成 |
| 版本4 | 随机数 | 最常用,无需任何信息 |
| 版本5 | SHA-1哈希(名字空间+名称) | 版本3的安全升级版 |
你之前看到的 NEWID() 生成的就是版本4(随机UUID)。
📊 总结对比
| 维度 | 说明 |
|---|---|
| 本质 | 128位全局唯一标识符 |
| UUID vs GUID | 同一标准,不同命名(开源世界 vs 微软世界) |
| 重复概率 | 极低(需要生成 2^122 次才可能重复一次) |
| 主要价值 | 无需中央协调,任何地方都能生成唯一ID |
| SQL Server 函数 | NEWID()(随机)、NEWSEQUENTIALID()(递增) |
| 使用场景 | 分布式主键、会话ID、文件命名、事件追踪 |
| 缺点 | 占用空间大(16字节 vs 自增ID的4字节),人类不友好 |
简单记住:UUID/GUID 就是"身份证号",让计算机世界里的每一样东西都有一个永久的、全球唯一的身份标识