UUID是什么?UUID生成原理、版本区别与使用场景详解

了解UUID是什么、UUID的结构和生成原理,掌握UUID v1、v3、v4、v5等版本区别,以及UUID在数据库、API、文件系统和分布式系统中的应用。

UUID是什么?UUID生成原理、版本区别与使用场景详解

在软件开发过程中,经常需要为用户、订单、文件、设备和数据库记录生成一个唯一标识。

例如:

  • 用户 ID
  • 订单 ID
  • 文件 ID
  • API 请求 ID
  • 设备 ID
  • 数据库记录 ID
  • 分布式系统中的业务对象 ID

传统系统通常使用数据库自增 ID:

1
2
3
4
5

这种方式简单、高效,但在分布式系统、数据迁移和多数据库环境中可能存在一些限制。

例如多个服务同时生成 ID:

服务A:1
服务B:1

如果两个服务的数据最终需要合并,就可能出现 ID 冲突。

UUID 就是解决唯一标识问题的一种常见方案。

UUID 可以在不同机器、不同服务甚至不同数据库之间生成,而不需要依赖一个中心化的 ID 生成器。


什么是UUID?

UUID 全称:

Universally Unique Identifier

中文通常称为:

通用唯一标识符

UUID 是一种用于标识信息的标准格式。

常见 UUID:

550e8400-e29b-41d4-a716-446655440000

UUID 通常由 32 个十六进制数字组成,并使用连字符分成多个部分。

常见格式:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

其中:

  • x 表示十六进制数字
  • M 表示 UUID 版本
  • N 表示 UUID 的变体信息

一个标准 UUID 通常占用:

128 bit

也就是:

16 bytes

UUID长什么样?

最常见的 UUID v4 示例:

550e8400-e29b-41d4-a716-446655440000

拆分后:

550e8400
-
e29b
-
41d4
-
a716
-
446655440000

总共:

8-4-4-4-12

个十六进制字符。

因此 UUID 字符串通常包含:

32个十六进制字符
+
4个连字符

如果去掉连字符:

550e8400e29b41d4a716446655440000

仍然对应 128 bit 的 UUID 数据。


UUID为什么可以保证唯一?

UUID 的核心目标是:

在实际应用环境中,以极低的概率产生重复标识。

UUID 并不是数学意义上绝对不会重复。

例如 UUID v4 使用大量随机位生成标识符,理论上仍然存在碰撞可能。

但是可用空间非常大,因此在合理的随机数生成条件下,碰撞概率非常低。

UUID 的优势在于:

不需要中央服务器
        ↓
不同机器可以独立生成
        ↓
不同服务可以独立生成
        ↓
不需要提前申请ID
        ↓
碰撞概率极低

这也是 UUID 非常适合分布式系统的重要原因。


UUID有多少种版本?

UUID 并不是只有一种生成方式。

常见 UUID 版本包括:

版本名称主要特点
UUID v1基于时间时间戳、节点等信息
UUID v3基于名称MD5 + Namespace
UUID v4随机随机数生成
UUID v5基于名称SHA-1 + Namespace
UUID v6时间排序改进时间字段布局
UUID v7Unix时间时间戳 + 随机数据
UUID v8自定义为特定应用提供自定义空间

实际开发中最常见的是:

UUID v4

近年来,如果需要数据库排序、日志追踪或高性能分布式 ID,UUID v7 也越来越受到关注。


UUID v1是什么?

UUID v1 是基于时间生成的 UUID。

它主要使用:

  • 时间信息
  • 时钟序列
  • 节点标识信息

生成 UUID。

UUID v1 的一个重要特点是:

包含时间相关信息。

因此它相比完全随机的 UUID 更具有一定的时间顺序特征。

不过 UUID v1 也存在一些需要注意的问题。

由于其生成机制可能包含节点相关信息,因此如果应用对隐私或信息暴露比较敏感,需要谨慎使用。


UUID v3是什么?

UUID v3 是基于名称生成 UUID。

它使用:

Namespace
+
Name
+
MD5

生成 UUID。

其特点是:

相同 Namespace 和相同 Name 会生成相同 UUID。

例如:

Namespace + user@example.com

只要输入完全一致,生成结果就一致。

因此 UUID v3 更适合:

  • 稳定标识
  • 名称映射
  • 可重复生成 ID

不过 UUID v3 使用 MD5,而 MD5 已经不适合现代安全场景中的密码学安全需求。

因此如果需要基于名称生成 UUID,一般更倾向于使用 UUID v5。


UUID v4是什么?

UUID v4 是目前非常常见的一种 UUID。

它主要基于随机数据生成。

例如:

550e8400-e29b-41d4-a716-446655440000

其中大量内容来自随机数。

UUID v4 的优势:

  • 生成简单
  • 不需要数据库
  • 不需要中心服务
  • 不依赖业务数据
  • 适合分布式环境
  • 碰撞概率极低

因此很多 Web 项目都会直接使用 UUID v4 作为:

  • 数据 ID
  • 文件 ID
  • 请求 ID
  • 临时 Token 标识
  • 分布式业务对象 ID

UUID v5是什么?

UUID v5 和 UUID v3 类似,也是根据 Namespace 和 Name 生成固定 UUID。

区别在于:

UUID v3
→ MD5

UUID v5
→ SHA-1

基本结构:

Namespace
+
Name
↓
SHA-1
↓
UUID

它同样具有确定性。

也就是说:

相同Namespace
+
相同Name
↓
相同UUID

UUID v5 适合需要稳定生成唯一标识的场景。


UUID v6是什么?

UUID v6 是一种针对时间排序进行优化的 UUID 版本。

它与 UUID v1 有一定关系,但重新调整了时间字段的布局。

主要目标之一是:

让 UUID 的字符串表示具有更好的时间排序特性。

传统 UUID v1 的字段布局并不适合直接进行字典序排序。

UUID v6 对时间字段进行重新排列后,更适合:

  • 数据库索引
  • 日志排序
  • 时间序列数据
  • 分布式系统

UUID v7是什么?

UUID v7 是近年来非常值得关注的一种 UUID 版本。

它使用 Unix 时间戳作为主要时间信息,并结合随机数据生成 UUID。

可以简单理解为:

时间戳
+
随机数据
↓
UUID v7

它同时兼顾:

  • 全局唯一标识
  • 时间排序
  • 分布式生成
  • 数据库索引友好性

例如:

时间
↓
UUID v7
↓
随着时间增长,整体具有更好的排序特征

因此 UUID v7 特别适合:

  • 数据库主键
  • 订单记录
  • 日志记录
  • 消息 ID
  • 分布式系统
  • 事件 ID

如果新系统需要 UUID,并且希望 UUID 具有较好的时间排序特性,可以重点考虑 UUID v7。


UUID v8是什么?

UUID v8 用于提供自定义 UUID 数据结构。

它允许应用根据自身需求定义部分数据。

因此 UUID v8 更适合:

  • 特定业务协议
  • 自定义标识结构
  • 特殊分布式系统
  • 兼容已有系统

但普通业务开发通常没有必要自行设计 UUID v8。

如果没有明确需求,一般优先考虑成熟的 UUID 版本。


UUID v4和UUID v7有什么区别?

UUID v4 和 UUID v7 都非常适合现代应用,但用途有所不同。

对比项目UUID v4UUID v7
主要方式随机时间戳 + 随机
是否包含时间信息
是否适合分布式系统
是否可以排序不适合时间排序更适合
数据库索引友好性一般更好
实现复杂度简单稍复杂
常见用途通用唯一 ID数据库、日志、分布式 ID

如果只是需要一个随机唯一标识:

UUID v4

通常就够了。

如果需要:

唯一
+
时间排序
+
数据库性能

可以考虑:

UUID v7

UUID和自增ID有什么区别?

这是数据库设计中非常常见的问题。

自增ID

例如:

1
2
3
4
5

优点:

  • 长度短
  • 索引效率高
  • 排序方便
  • 数据库支持好
  • 存储空间小

缺点:

  • 需要依赖数据库
  • 分布式环境处理复杂
  • 不同数据库容易产生冲突
  • 容易暴露数据规模

UUID

例如:

550e8400-e29b-41d4-a716-446655440000

优点:

  • 可以独立生成
  • 分布式友好
  • 全局唯一概率高
  • 不依赖中心数据库
  • 不容易直接推测数据量

缺点:

  • 字符串比较长
  • 索引占用空间较大
  • UUID v4 随机性可能导致数据库索引局部性较差
  • 不适合所有高性能数据库场景

UUID适合做数据库主键吗?

可以,但需要根据数据库和业务场景选择。

例如:

CREATE TABLE users (
    id CHAR(36) PRIMARY KEY,
    username VARCHAR(100)
);

这种方式可以直接保存 UUID 字符串。

但是:

CHAR(36)

会比整数类型占用更多空间。

如果数据量非常大,还需要考虑:

  • 索引大小
  • B+Tree 层级
  • 插入性能
  • Buffer Pool
  • 磁盘空间

因此数据库中不一定要直接使用字符串保存 UUID。


UUID在MySQL中的存储方式

如果使用 MySQL,可以考虑:

BINARY(16)

保存 UUID 的二进制形式。

例如:

CREATE TABLE users (
    id BINARY(16) PRIMARY KEY,
    username VARCHAR(100) NOT NULL
);

相比:

CHAR(36)

二进制存储可以减少存储空间。

常见方式:

UUID_TO_BIN(UUID())

读取时:

BIN_TO_UUID(id)

这种方式可以避免直接使用 36 字符 UUID 字符串作为数据库字段。


UUID在分布式系统中的作用

UUID 非常适合分布式系统。

假设有三个服务:

Service A
Service B
Service C

它们都需要创建订单。

如果使用数据库自增 ID:

Service A → 1
Service B → 1
Service C → 1

可能出现冲突。

而 UUID 可以让每个服务独立生成:

Service A
↓
UUID

Service B
↓
UUID

Service C
↓
UUID

不需要提前向中心服务申请编号。


UUID在微服务中的应用

在微服务架构中,经常会有:

  • 用户服务
  • 订单服务
  • 商品服务
  • 支付服务
  • 日志服务

不同服务可能使用不同数据库。

UUID 可以作为跨服务传递的业务标识。

例如:

用户创建订单
↓
Order Service
↓
生成 UUID
↓
订单ID
↓
Payment Service
↓
物流服务

多个系统可以使用同一个 UUID 标识订单。


UUID在API接口中的应用

REST API 中经常可以看到:

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

其中:

550e8400-e29b-41d4-a716-446655440000

就是资源 ID。

相比:

/users/1
/users/2
/users/3

UUID 不容易让用户直接判断资源数量和连续关系。

但需要注意:

UUID 不是权限控制机制。

即使使用 UUID,也必须在服务端进行权限验证。


UUID在文件系统中的应用

文件上传系统也经常使用 UUID。

例如用户上传:

avatar.png

服务器可以生成:

550e8400-e29b-41d4-a716-446655440000.png

这样可以降低不同用户上传同名文件产生冲突的概率。

常见流程:

用户上传文件
↓
生成UUID
↓
拼接文件扩展名
↓
保存文件
↓
数据库记录UUID

UUID在日志系统中的应用

分布式系统排查问题时,经常需要追踪一次请求经过了哪些服务。

可以为请求生成:

Request ID

例如:

550e8400-e29b-41d4-a716-446655440000

然后在多个服务中传递:

Gateway
↓
User Service
↓
Order Service
↓
Payment Service

所有日志都记录这个 ID。

最终可以通过 UUID 搜索完整请求链路。

这种方式在:

  • 微服务
  • API 网关
  • 链路追踪
  • 日志分析

中非常常见。


UUID在数据去重中的应用

UUID 还可以用于生成幂等请求 ID。

例如客户端发送支付请求:

POST /payment

请求携带:

Idempotency-Key:
550e8400-e29b-41d4-a716-446655440000

服务器可以记录这个 UUID。

如果客户端因为网络问题重复提交:

第一次请求
↓
UUID A

第二次请求
↓
UUID A

服务器发现已经处理过:

UUID A

就可以避免重复创建业务数据。


UUID是不是绝对唯一?

不是。

UUID 的名字虽然包含:

Universally Unique

但从数学上来说,并不能证明任意两个 UUID 永远不会重复。

特别是 UUID v4,本质上依赖随机数据。

理论上:

可能重复

但是合理生成的 UUID 拥有极大的取值空间。

因此实际工程中通常可以认为:

UUID 的碰撞概率极低,可以满足绝大多数业务系统的唯一标识需求。


UUID v4碰撞概率为什么很低?

UUID 总长度为:

128 bit

但 UUID v4 中有一部分 bit 用于表示版本和变体,因此真正用于随机数据的位数少于 128 bit。

即使如此,可用随机空间仍然非常大。

可以用生日悖论理解 UUID 碰撞。

当生成大量 UUID 时,碰撞概率会随着数量增长。

但是在正常业务规模下,UUID v4 的碰撞概率通常低到可以忽略。

需要注意:

UUID 的安全性和随机性取决于底层随机数生成器。

如果使用质量很差的随机数源,UUID 的实际可靠性也会下降。


UUID是不是加密算法?

不是。

UUID:

是唯一标识符。

它不是:

  • 加密算法
  • Hash 算法
  • 密码
  • Token
  • 数字签名

例如:

550e8400-e29b-41d4-a716-446655440000

并不能理解为加密后的数据。

UUID 主要解决的是:

如何为一个对象生成一个唯一标识。


UUID和Hash有什么区别?

Hash 和 UUID 都可以生成看起来类似的字符串,但用途不同。

对比UUIDHash
主要用途唯一标识数据摘要
输入是否必须固定不一定通常输入数据
是否可以验证数据变化不适合适合
是否主要用于唯一ID
常见算法v4、v7MD5、SHA-256
是否可逆不适用通常不可逆

例如:

UUID
→ 给订单生成ID

Hash:

文件
↓
SHA-256
↓
文件摘要

两者不能混为一谈。


UUID和数据库自增ID如何选择?

可以根据业务特点选择。

适合自增ID的情况

如果系统:

  • 单体应用
  • 单数据库
  • 数据量大
  • 追求索引性能
  • 不需要跨系统生成 ID

自增整数通常非常合适。

例如:

BIGINT AUTO_INCREMENT

适合UUID的情况

如果系统:

  • 微服务
  • 分布式架构
  • 多数据库
  • 多数据中心
  • 离线生成数据
  • 需要跨系统唯一标识

UUID 会更加方便。


UUID有哪些缺点?

虽然 UUID 很方便,但并不是所有场景都适合。

1. 占用空间更大

例如:

BIGINT

只需要 8 字节。

而 UUID 通常需要:

16 bytes

如果保存成字符串:

36 characters

索引占用空间会进一步增加。


2. UUID v4不适合天然排序

例如:

UUID A
UUID B
UUID C

随机 UUID 与创建时间没有直接关系。

如果数据库需要按照创建顺序处理数据,可能需要额外的:

created_at

字段。

或者选择 UUID v7 等具有时间排序特征的方案。


3. 可读性较差

相比:

10001
10002
10003

UUID:

550e8400-e29b-41d4-a716-446655440000

不适合人工阅读。


UUID最佳实践

使用 UUID 时,可以遵循以下原则。

1. 根据业务选择版本

普通随机 ID:

UUID v4

需要时间排序:

UUID v7

需要名称确定性:

UUID v5

不要为了使用 UUID 而盲目选择某个版本。


2. 数据库尽量考虑二进制存储

例如 MySQL:

BINARY(16)

相比:

CHAR(36)

通常可以降低存储和索引开销。


3. UUID不要替代权限控制

UUID 难以猜测,并不意味着安全。

例如:

GET /users/{uuid}

后端仍然需要检查:

当前用户
↓
是否拥有访问该资源的权限

4. 不要把UUID当作密码

UUID 可以作为:

ID
Request ID
Trace ID
文件ID

但不应该直接当作密码。


5. 选择可靠的UUID实现

不要自己手写复杂 UUID 算法。

优先使用成熟语言标准库或经过验证的 UUID 库。


Java生成UUID

Java 可以直接使用:

import java.util.UUID;

UUID id = UUID.randomUUID();

System.out.println(id);

输出类似:

550e8400-e29b-41d4-a716-446655440000

如果需要字符串:

String id = UUID.randomUUID().toString();

JavaScript生成UUID

现代 JavaScript 环境通常可以使用:

const id = crypto.randomUUID();

console.log(id);

输出:

550e8400-e29b-41d4-a716-446655440000

浏览器和 Node.js 的具体支持情况需要根据运行环境确认。


Python生成UUID

Python 提供了:

import uuid

id = uuid.uuid4()

print(id)

输出类似:

550e8400-e29b-41d4-a716-446655440000

生成字符串:

id = str(uuid.uuid4())

UUID常见使用场景

UUID 可以用于:

场景用途
用户系统用户唯一ID
订单系统订单唯一ID
文件系统文件唯一名称
微服务跨服务对象ID
API资源标识
日志Request ID
链路追踪Trace ID
消息系统Message ID
数据库主键或唯一键
幂等机制Idempotency Key
分布式系统全局唯一标识

在线UUID生成器有什么用?

如果只是临时需要 UUID,没有必要手动编写代码。

UUID 在线工具可以快速生成:

  • UUID v4
  • 批量 UUID
  • 随机 UUID
  • UUID 格式转换
  • 去除连字符
  • 大小写转换

例如:

在线UUID生成工具

基本使用方式:

打开UUID工具
↓
选择UUID版本
↓
设置生成数量
↓
点击生成
↓
复制UUID

UUID常见问题

UUID有多少位?

UUID 标准长度为:

128 bit

也就是:

16 bytes

通常表示为 36 个字符:

32个十六进制字符
+
4个连字符

UUID v4为什么最常见?

因为 UUID v4 生成方式简单,而且不依赖中心服务。

它非常适合:

  • Web 应用
  • 微服务
  • 分布式系统
  • 文件 ID
  • 数据 ID

等通用场景。


UUID v7比UUID v4好吗?

不能简单说谁更好。

如果只需要:

随机唯一ID

UUID v4 就很合适。

如果还需要:

时间排序
数据库索引友好

UUID v7 更有优势。


UUID可以当数据库主键吗?

可以。

但需要根据数据量和数据库类型考虑:

  • 存储空间
  • 索引大小
  • 插入性能
  • 排序需求
  • UUID版本

对于 MySQL 等数据库,还可以考虑使用:

BINARY(16)

保存 UUID。


UUID可以保证绝对不重复吗?

不能从数学意义上保证绝对不重复。

但在正确实现和合理随机源条件下,UUID 的碰撞概率通常极低,可以满足绝大多数实际应用需求。


UUID安全吗?

UUID 本身不是安全机制。

UUID v4 具有较强的随机性,但不能因此认为:

UUID = 安全Token

如果用于身份认证、密码重置或敏感操作,还需要使用专门设计的安全随机机制,并设置有效期、权限和其他安全控制。


UUID总结

UUID 是一种非常常见的通用唯一标识符。

它解决的核心问题是:

如何在不同系统、不同服务器和不同数据库环境中生成低碰撞概率的唯一 ID。

UUID 的常见版本包括:

UUID v1
UUID v3
UUID v4
UUID v5
UUID v6
UUID v7
UUID v8

其中:

v4

适合通用随机 ID。

v5

适合基于名称生成稳定 ID。

v7

适合需要时间排序特性的现代应用。

在数据库和分布式系统中,UUID 可以有效减少中心化 ID 生成服务的依赖,但也需要考虑存储空间、索引性能和排序问题。

如果项目只是需要一个简单的随机唯一标识,可以直接使用成熟的 UUID v4 实现。

如果系统需要同时兼顾:

全局唯一
+
分布式生成
+
时间排序
+
数据库性能

则可以进一步考虑 UUID v7。

在实际开发中,最重要的不是简单地选择 UUID,而是根据数据库、业务规模、分布式架构和性能要求选择合适的 ID 方案。

© 2026 IYA工作室