4.4 KiB
4.4 KiB
PostgreSQL SEQUENCE(序列)详解
语句解析
DROP SEQUENCE IF EXISTS "public"."adm_encounter_id_seq";
CREATE SEQUENCE "public"."adm_encounter_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 99999999
START 200
CACHE 1;
逐行解释
1. DROP SEQUENCE IF EXISTS "public"."adm_encounter_id_seq";
- 作用:如果序列已存在,先删除它
IF EXISTS:如果序列不存在,不会报错,直接跳过"public"."adm_encounter_id_seq":序列的完整名称public:模式(schema)名,默认模式adm_encounter_id_seq:序列名称
2. CREATE SEQUENCE "public"."adm_encounter_id_seq"
- 作用:创建一个新的序列
- 序列名称:
adm_encounter_id_seq(用于adm_encounter表的主键自增)
3. INCREMENT 1
- 作用:每次递增的步长
- 含义:每次调用
nextval()时,序列值增加 1 - 示例:如果当前值是 200,下次调用
nextval()返回 201
4. MINVALUE 1
- 作用:序列的最小值
- 含义:序列值不能小于 1
- 注意:如果序列达到最小值后继续递减,会报错(除非设置了
CYCLE)
5. MAXVALUE 99999999
- 作用:序列的最大值
- 含义:序列值不能超过 99999999(8位数)
- 注意:如果序列达到最大值后继续递增,会报错(除非设置了
CYCLE)
6. START 200
- 作用:序列的起始值
- 含义:序列从 200 开始
- 示例:第一次调用
nextval()返回 200,第二次返回 201,以此类推
7. CACHE 1
- 作用:缓存大小
- 含义:每次从数据库获取序列值时,预分配 1 个值到内存
- 说明:
CACHE 1:每次只缓存 1 个值(最安全,但性能较低)CACHE 20:每次缓存 20 个值(性能更好,但可能跳号)- 注意:如果数据库重启,缓存中未使用的序列值会丢失,导致跳号
使用示例
1. 在表定义中使用(自动自增)
CREATE TABLE "adm_encounter" (
"id" int8 NOT NULL DEFAULT nextval('adm_encounter_id_seq'::regclass),
...
);
2. 手动获取下一个值
-- 获取下一个序列值
SELECT nextval('adm_encounter_id_seq');
-- 返回:200(第一次调用)
SELECT nextval('adm_encounter_id_seq');
-- 返回:201(第二次调用)
3. 查看当前值(不递增)
SELECT currval('adm_encounter_id_seq');
-- 返回:当前序列值(不会增加)
4. 重置序列
-- 将序列重置为指定值
SELECT setval('adm_encounter_id_seq', 200);
实际应用场景
场景1:插入数据时自动生成ID
INSERT INTO adm_encounter (patient_id, organization_id, ...)
VALUES (123, 456, ...);
-- id 字段会自动使用序列的下一个值(如 200, 201, 202...)
场景2:手动指定ID(不推荐)
INSERT INTO adm_encounter (id, patient_id, ...)
VALUES (999, 123, ...);
-- 注意:如果手动插入的ID与序列值冲突,可能导致问题
注意事项
1. 序列与雪花算法的区别
- 序列:简单的数字递增(1, 2, 3...)
- 雪花算法:分布式ID生成算法(如:1996923066055286785)
- 当前项目:虽然定义了序列,但实际使用的是雪花算法(
IdType.ASSIGN_ID)
2. 序列跳号的原因
- 事务回滚:如果事务回滚,序列值不会回退
- 缓存:
CACHE > 1时,数据库重启可能导致跳号 - 手动插入:手动插入ID后,序列不会自动调整
3. 序列的优缺点
优点:
- 简单易用
- 性能好(预分配)
- 保证唯一性
缺点:
- 可能跳号
- 不适合分布式环境
- 最大值有限制
相关查询语句
查看序列信息
-- 查看序列的详细信息
SELECT
sequence_name AS 序列名称,
last_value AS 当前值,
start_value AS 起始值,
increment_by AS 递增步长,
max_value AS 最大值,
min_value AS 最小值,
cache_size AS 缓存大小
FROM information_schema.sequences
WHERE sequence_name = 'adm_encounter_id_seq';
查看序列的下一个值(不实际使用)
SELECT last_value, is_called
FROM adm_encounter_id_seq;
修改序列
-- 修改序列的起始值
ALTER SEQUENCE adm_encounter_id_seq RESTART WITH 1000;
-- 修改序列的最大值
ALTER SEQUENCE adm_encounter_id_seq MAXVALUE 999999999;
-- 修改序列的缓存大小
ALTER SEQUENCE adm_encounter_id_seq CACHE 20;