postgresql的id能否使用全局唯一的值

PostgreSQL 的 id 完全可以使用全局唯一的值,而且有多种成熟方案可选。关键是理解"全局唯一"的级别:表级唯一 vs 库级唯一 vs 分布式系统全局唯一


一、PostgreSQL 默认 ID 的局限性

sql

复制

-- 这些只是表级自增,无法保证全局唯一
id SERIAL PRIMARY KEY
id BIGSERIAL PRIMARY KEY
id INTEGER GENERATED ALWAYS AS IDENTITY

问题

  • 跨表可能重复(表A的id=1,表B的id=1)

  • 分布式环境下不同数据库实例会生成相同ID

  • 数据合并时会产生冲突


二、实现真正全局唯一的方案

方案1:UUID (最推荐)

sql

复制

-- 字段类型
id UUID PRIMARY KEY DEFAULT gen_random_uuid()

-- 需要启用扩展(PostgreSQL 13+ 内置)
CREATE EXTENSION IF NOT EXISTS pgcrypto;

优点

  • ✅ 真·全球唯一(跨表、跨库、跨服务器)

  • ✅ 无需协调中心,本地生成

  • ✅ 支持离线/分布式场景

  • ✅ 安全,不易被猜测

缺点

  • ❌ 占用16字节(比INT的4字节大)

  • ❌ 索引效率略低(但对现代硬件影响很小)

  • ❌ 人类不可读

适用:微服务、多租户、数据仓库、事件溯源


方案2:Snowflake ID (Twitter 算法)

生成64位整数(如 1234567890123456789),结构:

| 1位符号 | 41位时间戳 | 10位机器ID | 12位序列号 |

实现方式

  • 使用自定义函数生成

  • 使用外部ID生成服务(如美团 Leaf、百度 UID-Generator)

优点

  • ✅ 全局唯一

  • ✅ 趋势递增(对索引友好)

  • ✅ 占用8字节(BIGINT)

  • ✅ 包含时间信息

缺点

  • ❌ 需要部署独立服务或配置机器ID

  • ❌ 依赖系统时钟(时钟回拨会出问题)

适用:高并发、需要排序、性能敏感场景


方案3:组合键(业务语义ID)

sql

复制

-- 例如:订单ID = 时间 + 业务线 + 随机数
id VARCHAR(32) PRIMARY KEY DEFAULT generate_order_id()

生成逻辑

sql

复制

-- 示例:20231115 + 账号后6位 + 随机数
20231115876543001234

优点

  • ✅ 包含业务信息,可读性强

  • ✅ 全局唯一

缺点

  • ❌ 需要手写生成逻辑

  • ❌ 长度不固定

  • ❌ 可能泄露业务信息

适用:需要ID自解释的业务场景


方案4:全局序列序列 (Sequence)

sql

复制

-- 创建一个库级共享序列
CREATE GLOBAL SEQUENCE global_id_seq;

-- 所有表都用这个序列
id BIGINT PRIMARY KEY DEFAULT nextval('global_id_seq');

优点

  • ✅ 保证库级唯一

  • ✅ 整数类型,性能最好

缺点

  • ❌ 只在单库有效,多库仍重复

  • ❌ 有单点性能瓶颈

  • ❌ 需要管理权限

适用:单体应用、无分库场景


三、方案对比总结

表格

复制

特性UUIDSnowflake组合键全局序列
全局唯一性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
性能⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
可读性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
分布式支持⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
依赖时钟/服务业务逻辑数据库
存储空间16字节8字节变长8字节

四、选型建议

  • 90%场景:直接用 UUID,简单可靠,未来-proof

  • 超高并发+排序需求:用 Snowflake 风格的 ID

  • 遗留系统改造:用 全局序列 过渡

  • 特殊业务:用 组合键(如订单号)

现代应用黄金法则微服务架构下,无脑选 UUID,额外的存储成本远低于解决ID冲突的复杂度。


五、UUID 性能优化技巧

sql

复制

-- 1. 使用 UUID v7(时间有序,PostgreSQL 17+ 支持)
id UUID PRIMARY KEY DEFAULT gen_random_uuid_v7()

-- 2. 如果必须用UUID v4,可以创建索引时排序
CREATE INDEX idx_words_id ON words (id ASC);

PostgreSQL 15+ 对 UUID 索引已做了大量优化,性能差距已缩小到可忽略范围。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leijmdas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值