PostgreSQL 中序列(Sequence)的详细用法
🎈边走、边悟🎈迟早会好 |
一、序列的基本操作
1. 创建自定义序列
sql
-- 基本语法
CREATE SEQUENCE 序列名[INCREMENT BY 步长] -- 默认为1,可设为负数(递减)[START WITH 起始值] -- 默认为1[MINVALUE 最小值 | NO MINVALUE] -- 默认为1(递增时)[MAXVALUE 最大值 | NO MAXVALUE] -- 默认为2^31-1(int类型)[CACHE 缓存数量 | NO CACHE] -- 缓存序列值以提高性能,默认1[CYCLE | NO CYCLE]; -- 达到最大值后是否循环,默认不循环-- 示例:创建从100开始,步长为2的序列
CREATE SEQUENCE test_seqSTART WITH 100INCREMENT BY 2NO MAXVALUECACHE 1;
2. 序列与表关联
sql
-- 创建表时关联序列
CREATE TABLE test_table (id INT PRIMARY KEY DEFAULT nextval('test_seq'), -- 插入时自动取序列值content TEXT
);-- 已存在的表关联序列
ALTER TABLE existing_table
ALTER COLUMN id SET DEFAULT nextval('test_seq');
二、序列值的核心操作函数
函数 | 作用 | 示例 |
---|---|---|
nextval(序列名) | 生成下一个序列值(自动递增) | SELECT nextval('test_seq'); |
currval(序列名) | 获取当前会话最后生成的序列值 | SELECT currval('test_seq'); |
lastval() | 获取当前会话最后生成的任意序列值 | SELECT lastval(); |
setval(序列名, 值) | 直接设置序列的当前值 | SELECT setval('test_seq', 200); |
setval(序列名, 值, is_called) | 更精细设置,is_called 为false 时,下一次nextval 返回该值 | SELECT setval('test_seq', 200, false); |
三、重置序列值的常用场景
1. 重置序列为表中最大 ID 值(解决 ID 冲突)
当手动插入 ID 后,序列值可能落后于表中实际最大 ID,导致下次插入冲突,需同步序列:
sql
-- 语法:将序列值重置为表中最大ID + 1
SELECT setval('序列名', (SELECT COALESCE(MAX(id), 0) + 1 FROM 表名)
);-- 示例:同步test_table的序列与表中最大ID
SELECT setval('test_seq', (SELECT COALESCE(MAX(id), 0) + 1 FROM test_table)
);
COALESCE
用于处理表为空的情况(此时从 1 开始)。
2. 直接重置序列为指定值
sql
-- 重置序列为1000,下次nextval返回1001
SELECT setval('test_seq', 1000);-- 重置序列为1000,下次nextval返回1000(is_called=false)
SELECT setval('test_seq', 1000, false);
3. 重置序列为初始值(从头开始)
sql
-- 方法1:使用ALTER SEQUENCE(推荐,更直观)
ALTER SEQUENCE test_seq RESTART WITH 1; -- 下次nextval返回1-- 方法2:使用setval
SELECT setval('test_seq', 1, false); -- 效果同上
四、查看序列信息
1. 查看序列基本信息
sql
-- 查看序列当前值、起始值、步长等
SELECT * FROM test_seq;-- 或使用系统视图pg_sequences
SELECT * FROM pg_sequences WHERE sequencename = 'test_seq';
2. 查看表关联的序列
对于 SERIAL
或 IDENTITY
自动创建的序列,可通过以下方式找到关联的序列名:
sql
-- 语法:查询表中列关联的序列
SELECT pg_get_serial_sequence('表名', '列名');-- 示例:查询users表id列关联的序列
SELECT pg_get_serial_sequence('users', 'id'); -- 返回结果如:public.users_id_seq
五、删除序列
sql
-- 删除序列(若序列被表引用,需先解除关联)
DROP SEQUENCE IF EXISTS test_seq;-- 强制删除(即使被表引用,谨慎使用)
DROP SEQUENCE IF EXISTS test_seq CASCADE;
六、注意事项
- 序列与事务:
nextval
在事务中生成的值即使事务回滚也不会回退,可能导致 ID 间隙(正常现象,不影响唯一性)。 - 权限:操作序列需有
USAGE
权限,创建序列需有CREATE
权限。 IDENTITY
类型:对于GENERATED ALWAYS AS IDENTITY
列,重置序列后仍可正常使用,但手动插入 ID 需用OVERRIDING SYSTEM VALUE
。
通过上述操作,可以全面管理 PostgreSQL 中的序列,包括创建、关联、重置等场景,确保自增 ID 的正确生成。
🌟感谢支持 听忆.-CSDN博客
🎈众口难调🎈从心就好 |