Files
his/sql/sequence_explanation.md

4.4 KiB
Raw Permalink Blame History

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

  • 作用:序列的最大值
  • 含义:序列值不能超过 999999998位数
  • 注意:如果序列达到最大值后继续递增,会报错(除非设置了 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;