什么是UUID v7
UUID v7 是 RFC 9562 新增的版本,用来解决主键场景下 v4 的排序问题。前 48 位是毫秒精度的 Unix 时间戳,让 UUID 按生成先后排在相邻位置;其余 74 位是随机数,保证同一毫秒内生成的值也不会重复。
相比 v1,v7 不写入 MAC 地址,因此不会泄露机器信息;相比 v4,它保留了时间顺序。这就是它成为新系统主键默认选择的原因。
使用方法
- 在下拉框里选择 v7。
- 按需要设置数量,最多 1000 条。
- 点击生成 UUID 或按 Ctrl + Enter。
- 下载 CSV,即可直接导入数据库。
适用场景
- 数据库主键,尤其是数据量大、写入频繁的表。
- 需要按插入顺序分页的事件日志。
- 既想有唯一性又希望保持时间相关性的场景。
结构
前 48 位是毫秒时间戳;接着 4 位是版本号(7);然后是 12 位随机数和 2 位变体;最后 62 位仍是随机数。
UUID v7 的定位
| 选项 | 何时使用 |
|---|---|
v7 | 毫秒 Unix 时间,简单且可排序 |
v6 | 100 纳秒精度并保留节点字段,用于与 v1 兼容 |
v4 | 散布在整个索引中,写入频繁的主键不宜使用 |
UUID 各版本速查表
| 版本 | 可排序 | 数据来源 | 适合的场景 |
|---|---|---|---|
| v1 | 不可以 | 时间戳 + MAC 地址 | 仍在依赖 v1 的既有系统 |
| v3 | 不可以 | 名称的 MD5 哈希 | 必须使用 MD5 时的确定性标识符 |
| v4 | 不可以 | 122 位随机数 | 绝大多数普通的唯一标识需求 |
| v5 | 不可以 | 名称的 SHA-1 哈希 | 需要同一名称始终得到同一标识符 |
| v6 | 可以 | 重排后的时间戳 | 既要随机性又要便于排序 |
| v7 | 可以 | 毫秒精度的 Unix 时间 | 数据库主键和事件标识符 |
| v8 | 不可以 | 自定义位布局 | 专有格式和实验性用途 |
这七个版本都是 128 位,都用同样的 8-4-4-4-12 写法表示,区别只在于各个位代表什么。
代码示例
javascript
// 浏览器目前不提供 v7,需自行实现或引入库
const id = crypto.randomUUID();
python
# Python 3.14+
import uuid
id = str(uuid.uuid7())
csharp
// .NET 9+
var id = Guid.CreateVersion7().ToString();
sql
-- PostgreSQL 18+
SELECT uuidv7();
常见问题
为什么要用 v7 而不是 v4?
当这些值会成为带索引的主键时。v4 是随机分布的,每次插入都落在 B 树的不同位置,索引碎片和写放大都会上升。v7 的值集中在树的末端,写入开销明显更低。
v7 会暴露生成时间吗?
会,而且是故意如此 —— 前 48 位就是毫秒时间戳,任何拿到这个值的人都能算出生成时间。如果创建时间本身是敏感信息,请改用 v4。
v7 和 ULID 是一回事吗?
两者思路相同,都把时间戳放在高位以保证排序。区别在于 v7 是 RFC 标准,128 位,用十六进制表示;ULID 使用 Crockford base32,字符串更短。