UUID 类型
UUID(Universally Unique Identifier)是 128 位标识符。PostgreSQL 的 uuid 类型会校验格式并提供专用比较和索引,适合分布式生成、跨系统合并和避免暴露连续自增编号的场景。
格式和输入
CREATE TABLE accounts (
account_id uuid PRIMARY KEY,
email text NOT NULL
);
INSERT INTO accounts (account_id, email)
VALUES ('550e8400-e29b-41d4-a716-446655440000', 'a@example.com');
标准文本格式是 32 个十六进制数字和 4 个连字符。PostgreSQL 也接受部分等价写法,但 API 和日志应统一使用规范形式。UUID 不应保存为 char(36),否则失去类型校验和二进制存储优势。
生成 UUID
生成函数通常来自扩展或 PostgreSQL 版本提供的内置能力,部署时先确认环境:
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE jobs (
job_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
created_at timestamptz NOT NULL DEFAULT now()
);
不同版本还可能提供 UUID v4、v7 等生成函数。随机 UUID 适合不可预测的标识;时间有序 UUID 可改善某些 B-tree 写入局部性,但仍需核对版本、函数和隐私含义。
UUID 与自增整数
| 维度 | UUID | 自增整数 |
|---|---|---|
| 分布式生成 | 容易 | 通常需要协调序列 |
| 可读性 | 较差 | 较好 |
| 索引和存储 | 16 字节,随机版本可能导致页分裂 | 通常更紧凑且有序 |
| 可猜测性 | 随机版本较难猜 | 连续编号容易枚举 |
| 排障 | 需要复制完整 ID | 日志中更短 |
主键只是内部标识。即使使用 UUID,也应在 API 层做授权检查,不能把“难猜”当作访问控制。
索引、外键和展示
PRIMARY KEY 会自动创建 B-tree 索引;外键列也应建立索引以支持关联更新和删除。随机 UUID 在高写入量表中可能增加索引碎片和缓存压力,需通过基准测试评估。
展示给用户时可使用短码或独立的业务编号,不必强迫用户输入完整 UUID。日志中应统一大小写和格式,避免同一标识出现多种文本表示。
常见误区
- 把 UUID 当密码或授权令牌,忽略过期、撤销和权限校验。
- 每张表都盲目使用随机 UUID,却没有评估索引写入和存储成本。
- 使用字符串列保存 UUID,允许拼写错误和不同长度。
- 依赖 UUID 的随机性隐藏敏感业务信息,实际仍在 API 返回了可推断数据。