金仓数据库自增主键解决方案:序列(SEQUENCE) 解析

88 阅读7分钟

在这里插入图片描述

一、序列概述

1.1 什么是序列

序列(SEQUENCE)是KingbaseES数据库中的一种特殊数据库对象,用于自动生成一组具有规律性变化(递增或递减)的连续不同序列号。序列最常见的应用场景是为表的主键列自动生成唯一标识值。

1.2 序列的优势

相比手动编写程序生成顺序值,使用序列具有以下优势:

  • 自动化管理:无需编写复杂的程序逻辑
  • 并发安全:支持多用户并发访问,自动保证值的唯一性
  • 高性能:通过缓存机制提高访问效率
  • 可靠性强:确保主键列没有重复值
  • 灵活共享:一个序列可以为多个表生成主键

二、创建序列

2.1 权限要求

  • 在自己的模式中创建序列:需要 CREATE SEQUENCE 系统权限
  • 在其他用户模式中创建序列:需要 CREATE ANY SEQUENCE 权限

2.2 创建语法示例

以下示例创建一个用于生成学生编号的序列:

CREATE SEQUENCE stu_sequence
    INCREMENT BY 1        -- 每次递增1
    START WITH 1000       -- 起始值为1000
    MINVALUE 1000         -- 最小值1000
    MAXVALUE 9999         -- 最大值9999
    CACHE 100             -- 缓存100个序列号
    NOCYCLE;              -- 达到最大值后不循环

2.3 关键参数说明

参数说明示例
INCREMENT BY序列号递增/递减幅度INCREMENT BY 1
START WITH序列起始值START WITH 1000
MINVALUE序列最小值MINVALUE 1000
MAXVALUE序列最大值MAXVALUE 9999
CACHE内存中预分配的序列号数量CACHE 100
CYCLE/NOCYCLE达到极值后是否循环NOCYCLE

2.4 CACHE机制说明

优点:

  • 预先分配序列号到内存,大幅提高访问速度
  • 减少磁盘I/O操作

注意事项:

  • 实例异常关闭时,已缓存但未使用的序列号会丢失
  • 发生实例故障或执行 SHUTDOWN ABORT 时,序列号可能出现跳号

三、修改序列

3.1 权限要求

满足以下任一条件即可修改序列:

  • 序列在您的模式中
  • 拥有该序列的 ALTER 对象权限
  • 拥有 ALTER ANY SEQUENCE 系统权限

3.2 修改示例

ALTER SEQUENCE stu_sequence
    INCREMENT BY 2       -- 修改递增幅度为2
    CYCLE                -- 改为循环使用
    CACHE 20;            -- 修改缓存数量为20

3.3 修改注意事项

参数合理性检查

以下修改是不合理的(起始值1000,但最小值改为2000):

-- 错误示例
ALTER SEQUENCE stu_sequence
    INCREMENT BY 2
    MINVALUE 2000        -- 不合理:最小值大于起始值
    MAXVALUE 8000
    CYCLE
    CACHE 20;

修改原则:

  • 确保 MINVALUE ≤ START WITH ≤ MAXVALUE
  • 递增序列: INCREMENT BY > 0
  • 递减序列: INCREMENT BY < 0

四、使用序列

4.1 权限要求

  • 序列在您的模式中,或
  • 已被授予该序列的 SELECT 对象权限

4.2 NEXTVAL 和 CURRVAL 伪列

4.2.1 概念说明

伪列功能使用说明
NEXTVAL获取下一个序列号(指针后移)首次使用序列必须先调用NEXTVAL
CURRVAL获取当前序列号(指针不移动)必须在同一会话中先调用过NEXTVAL

4.2.2 NEXTVAL 使用示例

查看下一个序列号:

SELECT stu_sequence.NEXTVAL FROM dual;

执行结果:

NEXTVAL
----------
2000

INSERT语句中使用:

INSERT INTO student VALUES (
    stu_sequence.NEXTVAL, 
    '张丽',
    '女',
    18,
    '高中二年级',
    2,
    '105@qq.com',
    SYSDATE
);

UPDATE语句中使用:

UPDATE student 
SET student_id = stu_sequence.NEXTVAL 
WHERE student_id = 2022;

4.2.3 CURRVAL 使用示例

前提条件: 当前会话中必须已调用过 NEXTVAL

-- 使用相同的序列号插入多条记录
INSERT INTO student VALUES (
    stu_sequence.CURRVAL,  -- 使用当前序列号
    '刘意','女',17,'高中一年级',4,'106@qq.com',SYSDATE
);

INSERT INTO student VALUES (
    stu_sequence.CURRVAL,  -- 仍然是相同的序列号
    '赵文','男',19,'高中一年级',5,'107@qq.com',SYSDATE
);

注意: 如果列定义了主键约束,使用相同的 CURRVAL 插入多行会导致主键冲突错误。


五、序列缓存优化

5.1 缓存机制原理

序列缓存将序列号预先加载到内存中,避免每次都从磁盘读取,显著提升访问性能。

缓存结构:

  • 缓存由多个条目(Entry)组成
  • 每个条目可保存单个序列的多个序列号
  • 当缓存中的序列号用完时,自动从磁盘加载下一批

5.2 缓存优化指南

5.2.1 确定合适的缓存大小

低并发场景:

CREATE SEQUENCE low_concurrency_seq
    CACHE 20;  -- 较小的缓存即可

高并发场景:

CREATE SEQUENCE high_concurrency_seq
    CACHE 500;  -- 增大缓存以应对高并发

5.2.2 缓存大小设置建议

应用场景推荐CACHE值说明
低频访问10-50减少内存占用
中等并发50-200平衡性能和资源
高并发200-1000优先保证性能
超高并发1000+根据实际测试调整

5.2.3 缓存容量规划

如果应用程序并发使用大量序列:

  • 确保缓存能容纳所有活跃序列
  • 避免频繁的磁盘读取操作
  • 监控缓存命中率,适时调整

5.3 缓存示例

-- 创建缓存50个序列号的序列
CREATE SEQUENCE seq_test2
    CACHE 50;

当首次访问该序列时,系统会一次性生成并缓存50个序列号,后续49次访问都将直接从内存获取。


六、删除序列

6.1 权限要求

  • 删除自己创建的序列:无需额外权限
  • 删除其他用户的序列:需要 DROP ANY SEQUENCE 系统权限

6.2 删除语法

DROP SEQUENCE stu_sequence;

6.3 删除后果

重要提示:

  • 序列删除后,数据字典中的相关信息将被永久清除
  • 已使用该序列的表数据不受影响
  • 无法恢复已删除的序列(除非通过备份)

七、序列信息查询

7.1 数据字典视图

KingbaseES提供三个视图用于查询序列信息:

视图名称描述适用场景
USER_SEQUENCES当前用户拥有的序列查询自己的序列
ALL_SEQUENCES当前用户可访问的所有序列查询有权限访问的序列
DBA_SEQUENCES系统中所有序列管理员全局查询

7.2 查询示例

7.2.1 查询特定序列的关键信息

SELECT 
    min_value,           -- 最小值
    max_value,           -- 最大值
    increment_by,        -- 递增幅度
    last_number,         -- 最后生成的序列号
    cycle_flag           -- 是否循环
FROM dba_sequences
WHERE sequence_name = 'STU_SEQUENCE';

7.2.2 查询序列的完整信息

SELECT *
FROM dba_sequences
WHERE sequence_name = 'STU_SEQUENCE';

7.2.3 查询当前用户的所有序列

SELECT 
    sequence_name,       -- 序列名称
    min_value,
    max_value,
    increment_by,
    last_number,
    cache_size,          -- 缓存大小
    cycle_flag
FROM user_sequences
ORDER BY sequence_name;

7.3 常用查询字段说明

字段名说明示例值
sequence_name序列名称STU_SEQUENCE
min_value最小值1000
max_value最大值9999
increment_by递增值1
last_number最后生成的序列号2022
cache_size缓存大小100
cycle_flag是否循环(Y/N)N

八、最佳实践建议

8.1 命名规范

建议采用统一的命名规范:

-- 推荐格式: 表名_seq 或 表名_列名_seq
CREATE SEQUENCE student_seq;
CREATE SEQUENCE order_order_id_seq;

8.2 性能优化建议

  1. 合理设置CACHE值

    • 根据并发量动态调整
    • 高并发场景建议CACHE ≥ 200
  2. 避免频繁修改序列

    • 序列定义应在设计阶段确定
    • 频繁修改会影响性能
  3. 监控序列使用情况

    -- 检查序列是否即将达到上限
    SELECT 
        sequence_name,
        last_number,
        max_value,
        ROUND((last_number / max_value) * 100, 2) AS usage_percent
    FROM user_sequences
    WHERE ROUND((last_number / max_value) * 100, 2) > 80;
    

8.3 安全性建议

  1. 权限最小化原则

    • 仅授予必要的SELECT权限
    • 避免授予ALTER或DROP权限
  2. 定期备份序列定义

    -- 导出序列创建语句
    SELECT 'CREATE SEQUENCE ' || sequence_name || 
           ' START WITH ' || last_number || 
           ' INCREMENT BY ' || increment_by || 
           ' CACHE ' || cache_size || ';'
    FROM user_sequences;
    

8.4 故障处理建议

问题: 序列号出现跳号

原因分析:

  • 实例异常关闭导致缓存丢失
  • 事务回滚但序列号已消耗

解决方案:

  • 如果业务允许跳号,无需处理
  • 如果必须连续,考虑使用触发器补充逻辑

九、总结

序列是KingbaseES数据库中管理自增主键的核心机制,通过合理使用序列可以:

简化开发: 自动生成唯一标识,无需手动编码
保证性能: 缓存机制显著提升并发访问效率
确保可靠: 多用户环境下自动保证值的唯一性
灵活管理: 支持动态修改参数以适应业务变化

掌握序列的创建、使用、优化和监控,是数据库管理员和开发人员的必备技能。在实际应用中,应根据具体业务场景选择合适的参数配置,并定期监控序列使用情况,确保系统稳定高效运行。 在这里插入图片描述