本文目录导读:

UUID(通用唯一标识符) 是一种用于生成全球唯一标识的标准方法,它通过算法确保生成的标识符在时间和空间上几乎不可能重复,因此广泛应用于数据库主键、分布式系统、会话标识等场景。
以下是关于UUID生成的全面解析,包括格式、版本、生成方法及注意事项:
UUID的标准格式
一个UUID通常表示为32个十六进制数字,分为5组,用连字符分隔:
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
- M 表示版本号(如1、4)。
- N 表示变体(通常为8、9、a或b)。
- 示例:
550e8400-e29b-41d4-a716-446655440000
常见的UUID版本
| 版本 | 名称 | 生成方式 | 唯一性保证 | 主要用途 |
|---|---|---|---|---|
| v1 | 基于时间 | 当前时间戳 + 机器MAC地址 | 高(时间+机器) | 分布式追踪、日志记录 |
| v4 | 随机 | 完全随机数(122位随机位) | 极高(概率性) | 最常用,通用场景 |
| v3 | 基于命名空间+MD5 | 输入名称+命名空间的MD5哈希 | 对同一输入相同 | 确定性UUID(如URL映射) |
| v5 | 基于命名空间+SHA-1 | 输入名称+命名空间的SHA-1哈希 | 对同一输入相同 | 比v3更安全(推荐替代v3) |
| v6/v7/v8 | 实验性 | 时间有序+随机 | 高+可排序 | 数据库索引优化(新标准) |
在各种环境中生成UUID
🐍 Python
import uuid # v4 随机UUID uid = uuid.uuid4() print(str(uid)) # f47ac10b-58cc-4372-a567-0e02b2c3d479 # v1 基于时间 print(uuid.uuid1()) # v5 基于命名空间 url_uuid = uuid.uuid5(uuid.NAMESPACE_URL, "https://example.com")
📦 JavaScript/Node.js
// 浏览器(Crypto API)
const uid = crypto.randomUUID();
console.log(uid); // "550e8400-e29b-41d4-a716-446655440000"
// Node.js(内置crypto)
const { randomUUID } = require('crypto');
console.log(randomUUID());
// 或使用npm库 uuid
const { v4: uuidv4 } = require('uuid');
console.log(uuidv4());
☕ Java
import java.util.UUID; // v4 随机 UUID uid = UUID.randomUUID(); System.out.println(uid.toString()); // "c9b2f3a1-7e4d-4b8f-9a1c-2d3e4f5a6b7c"
🐘 PostgreSQL
-- 安装扩展(一次) CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- v4 随机 SELECT uuid_generate_v4(); -- v1 时间 SELECT uuid_generate_v1();
💻 命令行
# Linux/Mac (利用 /proc/sys/kernel/random/uuid) cat /proc/sys/kernel/random/uuid # 或使用uuidgen工具 uuidgen
什么时候选择哪个版本?
| 场景 | 推荐版本 | 原因 |
|---|---|---|
| 大多数应用 | v4(随机) | 简单、无隐私问题、冲突概率极低 |
| 需要可排序 | v7(时间有序) | 对数据库索引友好,减少页分裂 |
| 分布式系统追踪 | v1(时间+MAC) | 可推断生成顺序和机器 |
| 相同输入需相同ID | v5(命名空间+SHA-1) | 确定性(如用户ID映射) |
| 需要保密 | v4 | 不泄露时间戳和MAC地址 |
注意:UUID的潜在问题
- 空间:UUID是128位(16字节),作为字符串存储需36字符,不适合超大规模高频写入(如百亿级)。
- 索引性能:v4是完全随机,作为数据库主键可能导致B-Tree索引碎片化。v7(时间有序)解决了此问题。
- 隐私:v1包含MAC地址和时间戳,可能泄露设备信息;v4无此风险。
- 冲突概率:v4随机UUID在生成约 (2^{61}) 个后,冲突概率才达到50%,对于绝大多数应用完全可靠。
超越UUID:新趋势(如果你的场景需要更高性能)
- ULID:26字符、可排序、基于时间(类似v7但更紧凑)。
- Snowflake(雪花算法):64位整数,时间+机器+序列(Twitter内部使用)。
- KSUID:27字符、可按时间排序、全球唯一。
- 最通用:直接用 UUID v4(随机),语言内置支持,无需额外依赖。
- 数据库优化:考虑 UUID v7(如PostgreSQL的
gen_random_uuid()或uuid_generate_v7()扩展)。 - 极高吞吐量:切换到 Snowflake 或 ULID。