UUID 生成:v1、v4、v5 及使用场景

通用# UUID# GUID# 随机数# 数据库
最后更新: 2026年5月21日7 分钟阅读HSM Kit 团队
现在需要计算吗?
使用我们免费的在线 UUID 生成器 工具。

UUID(通用唯一标识符)是 128 位标识符,用于在分布式系统中唯一标识信息。它们无处不在——在数据库、API、文件名和交易 ID 中。本文涵盖 UUID 版本、随机性属性、碰撞概率,以及如何为您的应用程序选择正确的版本。

什么是 UUID?

UUID 是一个 128 位数字,通常显示为 5 组由连字符分隔的 32 个十六进制字符:

550e8400-e29b-41d4-a716-446655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
                 ↑    ↑
                 M = 版本(4)
                 N = 变体(10xx)

可能的 UUID 总数为 2^128 ≈ 3.4 × 10^38——这个数字如此之大,以至于碰撞实际上是不可能的。

UUID 版本

版本 1(时间戳 + MAC 地址)

d9b7e3a0-1f8c-11ee-95c4-0242ac120002
         ↑
         版本 1

结构:

  • 60 位时间戳(自 1582 年 10 月 15 日以来的 100 纳秒间隔)
  • 48 位生成计算机的 MAC 地址
  • 14 位时钟序列(处理时间戳碰撞)

属性:

  • 按时间排序:可按生成时间排序
  • 唯一:MAC 地址确保跨机器唯一性
  • 隐私问题:泄露 MAC 地址和生成时间

使用场景:

  • 需要按时间排序的 UUID
  • 需要在分布式系统中唯一
  • 隐私不是问题

版本 4(随机)

a1b2c3d4-e5f6-4789-abcd-ef0123456789
                 ↑
                 版本 4

结构:

  • 122 位随机数据
  • 4 位版本(0100)
  • 2 位变体(10)

属性:

  • 随机:无嵌入信息
  • 无需协调:独立生成
  • 隐私安全:无信息泄露
  • 不可排序:随机顺序

使用场景:

  • 需要简单的随机标识符
  • 隐私很重要
  • 不需要时间排序
  • 最常用的通用选择

版本 5(基于 SHA-1 的名称)

6ba7b810-9dad-11d1-80b4-00c04fd430c8
                 ↑
                 版本 5

结构:

  • 以命名空间 UUID 和名称作为输入
  • 计算组合的 SHA-1 哈希
  • 产生确定性输出(相同输入 = 相同 UUID)

属性:

  • 确定性:相同的命名空间 + 名称总是产生相同的 UUID
  • 无随机性:可重现
  • 抗碰撞:SHA-1 提供良好的分布

使用场景:

  • 需要从已知输入生成确定性 UUID
  • 多个系统必须为同一实体生成相同的 UUID
  • 示例:从 URL 生成 UUID、从域名生成 UUID

版本 3(基于 MD5 的名称)

与版本 5 相同的概念,但使用 MD5 代替 SHA-1:

  • 比版本 5 抗碰撞能力弱
  • 新系统应使用版本 5

UUID 格式详情

结构

八位字节: 0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      0   |                        time_low                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      4   |          time_mid             |  time_hi_and_version          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      8   |clk_seq_hi_res |  clk_seq_low  |         node (0-1)           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     12   |                         node (2-5)                            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

版本和变体位

版本位(M 位置)变体位(N 位置)
10001110xx
30011110xx
40100110xx
50101110xx

碰撞概率

对于版本 4(随机)UUID:

UUID 数量碰撞概率
10 亿10^18 分之一
1 万亿10^12 分之一
10^18~50% 几率

要有 50% 的几率至少发生一次碰撞,您需要生成大约 2.71 × 10^18 个 UUID。那是 271 亿亿个 UUID。

出于实际目的,版本 4 UUID 对于任何现实世界的应用都是无碰撞的。

生日问题

生日问题解释了为什么碰撞比直觉认为的更早变得可能。对于 n 个可能的值,您需要大约 √n 个项目才能有 50% 的碰撞几率。

对于 UUID:√(2^128) ≈ 1.8 × 10^19

版本 1 vs 版本 4

方面版本 1版本 4
排序按时间排序随机
唯一性来源MAC + 时间戳随机性
隐私泄露 MAC/时间无信息泄露
数据库性能良好(顺序插入)还行(随机插入)
需要协调
常见用途遗留系统现代应用

数据库考虑

版本 1 优势:

  • 按时间排序:对聚集索引更好
  • 顺序插入减少 B-tree 索引中的页面分裂

版本 4 劣势:

  • 随机:在聚集索引中导致索引碎片
  • 可以通过 UUID v7(时间排序随机)或 ULID 缓解

版本 7(草案):

  • 时间排序的随机 UUID
  • 两全其美
  • 尚未标准化

UUID 作为数据库主键

优势

  • 全局唯一:对分布式数据库安全
  • 无需协调:不需要自增序列
  • 合并安全:可以合并数据库而不冲突
  • 不透明:不泄露记录数量

劣势

  • 大小:16 字节 vs 4 字节(int)或 8 字节(bigint)
  • 索引碎片:随机 UUID 导致页面分裂
  • 不友好:难以调试

最佳实践

-- 对聚集索引使用版本 1 或 ULID
CREATE TABLE orders (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),  -- 版本 4
    -- 或
    id UUID PRIMARY KEY DEFAULT uuid_generate_v1(), -- 版本 1
    ...
);

-- 存储为 UUID 类型(不是 varchar)
-- PostgreSQL 有原生 UUID 类型
-- MySQL 存储为 BINARY(16) 或 CHAR(36)

API 中的 UUID

URL 参数

GET /users/550e8400-e29b-41d4-a716-446655440000

JSON 响应

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "John Doe"
}

请求 ID

UUID 通常用作分布式系统中的请求/关联 ID,用于跨服务跟踪请求。

UUID 替代方案

格式大小按时间排序示例
UUID v416 字节550e8400-e29b-41d4-...
UUID v116 字节d9b7e3a0-1f8c-11ee-...
ULID16 字节01ARZ3NDEKTSV4RRFFQ69G5FAV
NanoID可变V1StGXR8_Z5jdHi6B-myT
Snowflake8 字节492474761028608
CUID25 字符cjld2cyuq0000t3rmniod1foy

ULID(通用唯一字典排序标识符)

  • 128 位,与 UUID 相同
  • 按时间排序(可字典排序)
  • 编码为 26 字符的 Crockford Base32
  • 比随机 UUID 更适合数据库

NanoID

  • 可变长度(默认 21 字符)
  • URL 安全
  • 比 UUID 小
  • 适合短标识符

生成 UUID

JavaScript

// 版本 4(随机)
const uuid = crypto.randomUUID();
// "550e8400-e29b-41d4-a716-446655440000"

// 指定版本
import { v4 as uuidv4 } from 'uuid';
const id = uuidv4();

Python

import uuid

# 版本 4(随机)
id_v4 = uuid.uuid4()

# 版本 1(时间戳 + MAC)
id_v1 = uuid.uuid1()

# 版本 5(基于名称)
id_v5 = uuid.uuid5(uuid.NAMESPACE_URL, 'https://example.com')

命令行

# 使用 uuidgen(macOS/Linux)
uuidgen

# 使用 Python
python -c "import uuid; print(uuid.uuid4())"

# 使用 OpenSSL
openssl rand -hex 16 | sed 's/\(.\{8\}\)\(.\{4\}\)\(.\{4\}\)\(.\{4\}\)\(.\{12\}\)/\1-\2-\3-\4-\5/'

常见错误

错误问题解决方案
使用 UUID v4 作为主键索引碎片使用 v1、v7 或 ULID
存储为 VARCHAR(36)浪费空间使用原生 UUID 类型或 BINARY(16)
假设可排序UUID v4 是随机的使用 v1 或 ULID 进行排序
不索引 UUID 列查询缓慢始终索引 UUID 列
使用版本 3(MD5)比版本 5 弱对基于名称的 UUID 使用版本 5

支付系统中的 UUID

UUID 在支付系统中用于:

  • 交易 ID:每笔交易的唯一标识符
  • 关联 ID:跨服务跟踪请求
  • 终端 ID:标识 POS 终端
  • 批次 ID:分组相关交易

在线工具

使用 UUID 生成器

  • 生成不同版本的 UUID(v1、v4、v5)
  • 理解每个版本的结构和组件
  • 批量生成 UUID 用于测试
  • 验证现有 UUID

所有处理都在浏览器中进行——您的数据永远不会离开您的设备。

相关工具
UUID 生成器