使用postgresql seq生成序号
我来为您介绍 PostgreSQL 序列(Sequence)生成序号的完整用法。
1. 创建序列
-- 基本创建
CREATE SEQUENCE my_seq;
-- 完整参数创建
CREATE SEQUENCE order_seq
START WITH 1000 -- 起始值
INCREMENT BY 1 -- 步长
MINVALUE 1000 -- 最小值
MAXVALUE 999999999 -- 最大值
NO CYCLE -- 不循环(到达最大值报错)
CACHE 20; -- 缓存数量,提升性能
2. 使用序列获取序号
-- 获取下一个值(最常用)
SELECT nextval('order_seq');
-- 获取当前值(需要先执行过 nextval)
SELECT currval('order_seq');
-- 查看序列当前状态(不消耗值)
SELECT last_value FROM order_seq;
-- 设置序列值(慎用)
SELECT setval('order_seq', 5000);
3. 与表字段关联(推荐)
方式一:建表时直接指定
CREATE TABLE orders (
id BIGINT PRIMARY KEY DEFAULT nextval('order_seq'),
order_no VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
方式二:使用 SERIAL/BIGSERIAL(自动创建序列)
-- SERIAL = INTEGER + 自动创建序列
-- BIGSERIAL = BIGINT + 自动创建序列(推荐,防止溢出)
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY, -- 自动创建 users_id_seq
username VARCHAR(50) NOT NULL
);
4. 实际应用场景
生成业务订单号(带前缀+日期+序列)
-- 创建订单号序列
CREATE SEQUENCE order_no_seq START WITH 1 CACHE 100;
-- 生成格式:ORD-20260514-000001
SELECT 'ORD-' || TO_CHAR(CURRENT_DATE, 'YYYYMMDD') || '-' ||
LPAD(nextval('order_no_seq')::TEXT, 6, '0') AS order_no;
-- 结果:ORD-20260514-000001
批量获取序号(用于批量插入)
-- 一次获取多个值
SELECT nextval('order_seq') FROM generate_series(1, 100);
5. 序列管理
-- 查看所有序列
SELECT * FROM information_schema.sequences WHERE sequence_schema = 'public';
-- 修改序列
ALTER SEQUENCE order_seq RESTART WITH 2000; -- 重置起始值
ALTER SEQUENCE order_seq INCREMENT BY 10; -- 修改步长
-- 删除序列
DROP SEQUENCE IF EXISTS my_seq CASCADE; -- CASCADE 会解除关联表的依赖
6. 高并发与性能优化
策略 说明
CACHE 预分配序号到内存,减少磁盘 IO。CACHE 1000 适合高并发
NOORDER 默认不保证严格顺序,提升并发性能
CYCLE 到达最大值后循环使用(注意业务是否允许重复)
-- 高并发场景推荐配置
CREATE SEQUENCE high_perf_seq
CACHE 1000 -- 缓存 1000 个值
NO CYCLE;
7. 注意事项
1. 事务回滚不回收序号:nextval 获取的值即使事务回滚也不会归还,可能产生跳号
2. 主键冲突:手动插入指定 ID 后,序列不会自动更新,需执行 SELECT setval('seq', MAX(id)) FROM table
3. 迁移数据时:导入数据后务必重置序列起始值,避免 nextval 冲突
-- 数据迁移后重置序列
SELECT setval('users_id_seq', COALESCE((SELECT MAX(id) FROM users), 0) + 1, false);
8. 与 MySQL AUTO_INCREMENT 对比
特性 PostgreSQL Sequence MySQL AUTO_INCREMENT
独立对象 ✅ 是 ❌ 否
多表共享 ✅ 可以 ❌ 不行
自定义规则 ✅ 灵活 ❌ 有限
获取当前值 currval() LAST_INSERT_ID()
需要针对具体业务场景(如分布式 ID、雪花算法替代方案等)的详细方案吗?
更多推荐



所有评论(0)