toolfree

UUID 产生器

在浏览器中批次产生随机的 v4 UUID 或依时间排序的 v7 UUID,并说明数据库主键该选哪一种、为什么。

在你的浏览器中运行

该用 v4 还是 v7

v4 UUID 是 122 个随机比特。v7 UUID 把开头 48 个比特换成 Unix 毫秒时间戳,其余仍是随机值。两者都是 128 比特、都写成 36 个字元,实务上都不会重复。差别在于顺序

v4  9f8b3c12-5d4e-4a7b-8c19-2f6e0a5b7d31
v7  0198c4a1-7e2f-7c33-b8d0-5a1c9e7f2b64
     └──── 自 1970 年起的毫秒数 ────┘

把一串 v7 UUID 当字串排序,顺序就是产生的先后;v4 排出来则是一团杂讯。

这对数据库为什么重要

多数关联式数据库会以主键建立 B-tree 来存放数据表。以随机顺序写入代表每一笔都落在不同的页面: 工作集从索引的尾端变成整个索引,页面分裂大量增加,写入吞吐量会随着数据表变大而下降。以大致递增 的顺序写入,则只会一直附加在同一个热页面上。

这就是 MySQL 长年建议不要用随机 UUID 当主键的原因,也是 v7 被标准化的原因——它在 2024 年 5 月 随 RFC 9562 定案,同时纳入 v6 与 v8,取代了 RFC 4122。

要写进有索引的栏位、而且让人看出大概的建立时间也无妨的数据,选 v7。若识别码会公开露出、且不能 泄漏任何信息,选 v4:拿到一个 v7 值的人,可以精确到毫秒推知那笔数据是什么时候建立的。

版本与变体的位置

规格固定了两个位置,它们不是随机的:

所以 v4 UUID 实际只有 122 个自由比特,而不是 128 个。这仍然足够让碰撞不成为实际问题——大致要 每秒产生十亿个、持续数十年,才会开始需要担心。

在程序中产生

crypto.randomUUID()                       // v4,浏览器与 Node 19 以上
SELECT gen_random_uuid();                 -- PostgreSQL 13 以上,v4
import uuid; uuid.uuid4()

v7 目前在多数标准函式库还没有内建;PostgreSQL 从 18 版起提供 uuidv7()。在那之前得靠套件,或是 自己写几行把时间戳填进前六个字节。

你的数据只留在这里

这些值由浏览器的 crypto.getRandomValues 产生,那是平台提供的密码学安全乱数来源。没有任何值在 服务器上产生,也没有任何纪录,所以你从这个页面取走的 UUID 只有你自己的电脑看过。