HSM KitHSM Kit
中文

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

General# UUID# GUID# 随机数# 数据库
Last Updated: 2026年5月21日7 min readBy HSM Kit Team
Need to calculate this now?
Use our free online UUID 生成器 tool.

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

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

Related Tool
UUID 生成器