☰
用 PostgreSQL pgcrypto 扩展的 gen_random_uuid() 生成随机 v4 UUID
2026/10/8 13:14:22 网站建设 项目流程
  • 文档
  • 教程
  • 知识库

【免费下载链接】til

:memo: Today I Learned

项目地址:https://gitcode.com/gh_mirrors/ti/til
点击查看免费下载

本篇指南围绕本仓库 postgres/generating-uuids-with-pgcrypto.md 记录的核心结论展开:当只需要随机生成的 v4 UUID 时,应优先使用pgcrypto扩展自带的gen_random_uuid()函数,而不是维护状况不佳的uuid-ossp扩展。读完本文,你将掌握 pgcrypto 的安装与使用、v4 UUID 的结构特征、gen_random_uuid()在 PostgreSQL 各版本中的演进,以及它在表结构迁移中的实战用法。

为什么弃用 uuid-ossp:官方文档给出的明确信号

在 PostgreSQL 的uuid-ossp扩展文档中,官方针对其底层依赖 OSSP UUID 库给出了这样一段警示:

The OSSP UUID library... is not well maintained, and is becoming increasingly difficult to port to newer platforms.

(OSSP UUID 库……维护不力,且越来越难以移植到更新的平台。)

紧接着,官方文档给出了明确的替代建议:

If you only need randomly-generated (version 4) UUIDs, consider using the gen_random_uuid() function from the pgcrypto module instead.

(如果你只需要随机生成(第 4 版)UUID,请考虑改用 pgcrypto 模块中的 gen_random_uuid() 函数。)

这段建议是本文的核心前提:PostgreSQL 已经内置了uuid数据类型(参见仓库笔记 postgres/generate-a-uuid.md),如果我们的使用场景只是为uuid列生成随机值,完全没有必要引入维护状况欠佳的uuid-ossp,直接依托pgcrypto即可。

快速上手:安装 pgcrypto 并生成 v4 UUID

pgcrypto是随 PostgreSQL 一起分发的扩展,安装一条命令即可:

> create extension "pgcrypto"; CREATE EXTENSION

安装后,即可调用其中的gen_random_uuid()函数,该函数生成的正是随机 v4 UUID:

> select gen_random_uuid(); gen_random_uuid -------------------------------------- 0a557c31-0632-4d3e-a349-e0adefb66a69 > select gen_random_uuid(); gen_random_uuid -------------------------------------- 83cdd678-8198-4d56-935d-d052f2e9db37

每次调用都会返回不同的值。从上面的输出可以观察 v4 UUID 的结构特征:第 13 个十六进制字符固定为4(表示版本号为 4),紧接着的字符为a(表示变体位)。在示例中,4d3e中的4与a349中的a恰好印证了这一点——这正是 RFC 4122 定义的 v4 布局:128 位中除版本位与变体位外,其余 122 位由随机数填充。

gen_random_uuid() 在 PostgreSQL v13 之后的演进

需要说明一个重要版本差异:早期版本中gen_random_uuid()依赖pgcrypto扩展,但自 PostgreSQL v13 起,该函数已被并入核心功能,无需安装任何扩展即可直接使用。仓库中的笔记 postgres/generate-random-uuids-without-an-extension.md 记录了这个事实:

> select gen_random_uuid(); gen_random_uuid -------------------------------------- 0aa72fe6-ede7-4ccf-b328-348becc58066 (1 row)

因此在实际项目中可以这样决策:

  • PostgreSQL v13 及以上:直接使用gen_random_uuid(),连create extension都不需要;
  • PostgreSQL v13 以下:先create extension "pgcrypto";再使用同一函数;
  • 需要非 v4 版本的 UUID(如基于时间戳的 v1 等):才需要继续依赖uuid-ossp,详见 postgres/generate-a-uuid.md 中介绍的uuid_generate_v4()及其他生成函数。

顺带一提,仓库中还有一篇 postgres/install-postgres-with-uuid-ossp-using-asdf.md,记录了一个常见坑:通过asdf安装 PostgreSQL 时默认不包含uuid-ossp扩展,会报出uuid-ossp.control file missing in extention folder之类的错误,需要借助POSTGRES_EXTRA_CONFIGURE_OPTIONS="--with-uuid=e2fs"等额外配置项才能装上。这从侧面再次说明:能少依赖一个扩展,就少一分环境适配成本。

pgcrypto 不止 UUID:同模块的加密能力佐证

pgcrypto扩展提供的是一个加密工具函数集合,gen_random_uuid()只是其中面向 UUID 场景的一小部分。本仓库中还有多篇笔记可以相互印证其能力边界:

  • 哈希计算:digest()函数支持md5、sha1、sha224、sha256、sha384、sha512等算法,见 postgres/compute-hashes-with-pgcrypto.md;
  • 随机字节生成:gen_random_bytes(n)可以生成指定长度的加密级随机字节,仓库笔记 postgres/generate-random-alphanumeric-identifier.md 正是用它配合 CTE 生成随机的短标识符;
  • 密码加盐哈希:crypt()与gen_salt()组合可做加盐密码存储与校验,见 postgres/salt-and-hash-a-password-with-pgcrypto.md。

这些笔记共同说明:gen_random_uuid()依赖的正是 pgcrypto 底层的加密随机数能力,而非普通的伪随机数生成器——这也是其适合用作主键等安全敏感场景的原因。

实战:将 gen_random_uuid() 用于表结构迁移

在实际项目中,gen_random_uuid()最常见的落地场景之一,是把现有整型主键列迁移为 UUID 类型。由于 PostgreSQL 无法自动把int转成uuid,需要借助ALTER TABLE的using子句显式指定转换逻辑。仓库笔记 postgres/switch-non-castable-column-type-with-using-clause.md 给出了完整示例:

alter table users alter column id set data type uuid using (gen_random_uuid());

这里using子句的作用是:忽略原列中已有的整型id值,改用gen_random_uuid()为每一行生成全新的 UUID 填充。由于该笔记中调用的是无前缀的函数名,也印证了在 v13+ 环境下gen_random_uuid()已是内置函数这一事实。

三种生成方式速查对比

方案适用版本扩展依赖适用场景
pgcrypto的gen_random_uuid()v13 以下需pgcrypto;v13 起内置需create extension "pgcrypto";只需要随机 v4 UUID,官方推荐
uuid-ossp的uuid_generate_v4()各版本需create extension "uuid-ossp";需要非 v4 版本的 UUID 函数
内置gen_random_uuid()v13 及以上无随机 v4 UUID 的最简方案

需要留意的是,不同环境的扩展安装方式可能存在差异(例如 postgres/install-postgres-with-uuid-ossp-using-asdf.md 中记录的自定义编译场景),在以迁移脚本或部署流程形式使用上述命令前,应先确认目标数据库版本与扩展可用性。

小结

  • 生成 v4 随机 UUID 时,官方文档明确建议使用pgcrypto的gen_random_uuid()而非维护状况不佳的uuid-ossp;
  • 在 PostgreSQL v13 及以上版本中该函数已内置,连扩展安装都可以省去;
  • 该函数基于 pgcrypto 的加密随机数能力,适合作为 UUID 主键、迁移脚本中的using子句转换逻辑等场景;
  • 若确实需要非 v4 的 UUID,再回到uuid-ossp,并注意其在不同安装方式下的额外配置成本。

如果你想继续深入,可以继续阅读本仓库的 postgres/generate-a-uuid.md、postgres/generate-random-uuids-without-an-extension.md 与 postgres/switch-non-castable-column-type-with-using-clause.md 三篇配套笔记,覆盖 UUID 生成方案的前世今生与迁移实战。

  • 文档
  • 教程
  • 知识库

【免费下载链接】til

:memo: Today I Learned

项目地址:https://gitcode.com/gh_mirrors/ti/til
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询