- 文档
- 教程
- 知识库
【免费下载链接】til
:memo: Today I Learned
本篇指南围绕本仓库 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
相关推荐
在 PostgreSQL 中使用 pgcrypto 与 CTE 生成加密安全的随机字母数字标识符
在 PostgreSQL 中使用 pgcrypto 与 CTE 生成加密安全的随机字母数字标识符 导读 本文介绍如何在 PostgreSQL 中仅用一条查询语句
文档教程知识库Instatic与GraphQL客户端:Apollo、Relay集成完整指南
Instatic与GraphQL客户端:Apollo、Relay集成完整指南 Instatic是一款现代自托管可视化CMS,它通过内置的插件系统提供了灵活的数据
CMS后端前端asyncpg与PostgreSQL扩展:pgcrypto非对称加密
asyncpg与PostgreSQL扩展:pgcrypto非对称加密 在现代应用开发中,数据安全是不可忽视的核心需求。特别是涉及用户隐私、支付信息等敏感数据时,
数据库后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考