0

0

什么是SQL的序列?SEQUENCE的创建与使用方法解析

星夢妙者

星夢妙者

发布时间:2025-09-04 21:44:01

|

1016人浏览过

|

来源于php中文网

原创

SQL序列是数据库中独立于表的自增计数器,用于生成唯一整数,适用于主键、订单号等场景。其核心优势在于跨表共享、提前获取值、高并发安全及灵活配置。通过CREATE SEQUENCE定义序列,支持设置起始值、步长、最大最小值、循环与缓存等参数;使用NEXTVAL获取下一个值,CURRVAL获取当前会话最新值。相比表级自增列,序列更灵活,可跨表使用,支持预分配ID,适合分布式系统、数据合并等复杂场景。CACHE提升性能但可能导致跳号,NO CYCLE确保主键唯一,多数场景接受非连续性以换取效率。序列在高并发、多表共用或需全局唯一ID时优势显著,是自增列的有效补充。

什么是sql的序列?sequence的创建与使用方法解析

SQL序列,说白了,就是数据库里一个能自动生成唯一数字的计数器。它独立于任何表存在,专门用来生成一系列按特定规则递增或递减的整数,我们通常用它来作为主键、订单号或者其他需要唯一标识的字段。在我看来,它最大的价值在于提供了一种灵活且并发安全的方式来管理这些数字,尤其是在那些不方便直接使用表级别自增字段的场景下。

解决方案

要使用SQL序列,核心就是两步:创建它,然后调用它。

创建序列

创建一个序列的语法相对直观,但有很多参数可以精细控制其行为。

CREATE SEQUENCE sequence_name
    [ INCREMENT BY increment_value ]
    [ START WITH start_value ]
    [ MINVALUE min_value | NO MINVALUE ]
    [ MAXVALUE max_value | NO MAXVALUE ]
    [ CYCLE | NO CYCLE ]
    [ CACHE cache_size | NO CACHE ];
  • sequence_name
    : 你给序列起的名字,要符合数据库的命名规范。
  • INCREMENT BY increment_value
    : 每次序列增加或减少的值,默认是1。
  • START WITH start_value
    : 序列的起始值,也就是第一次调用
    NEXTVAL
    时返回的值。
  • MINVALUE min_value
    : 序列能生成的最小值。
  • MAXVALUE max_value
    : 序列能生成的最大值。
  • CYCLE
    : 当序列达到
    MAXVALUE
    (或
    MINVALUE
    )后,是否循环回到
    MINVALUE
    (或
    MAXVALUE
    )继续生成。不指定就是
    NO CYCLE
    ,达到最大值后会报错。
  • CACHE cache_size
    : 数据库预先在内存中分配并存储多少个序列值。这能显著提高性能,减少磁盘I/O,但服务器重启或故障可能导致缓存中的部分值丢失(即产生跳号)。
    NO CACHE
    则每次都从数据字典中获取,更安全但性能可能稍差。

使用序列

创建好序列后,主要通过两个伪列(pseudo-column)来使用它:

  1. NEXTVAL
    : 获取序列的下一个值。每次调用都会让序列前进并返回新值。
  2. CURRVAL
    : 获取序列的当前值。这个值是当前会话中最近一次调用
    NEXTVAL
    后生成的值。需要注意的是,在一个会话中,必须先调用
    NEXTVAL
    ,才能使用
    CURRVAL
    ,否则会报错。

示例:

-- 创建一个名为 'order_id_seq' 的序列,从1000开始,每次递增1,不循环,缓存20个值
CREATE SEQUENCE order_id_seq
    START WITH 1000
    INCREMENT BY 1
    NO CYCLE
    CACHE 20;

-- 插入数据时使用序列生成主键
INSERT INTO orders (order_id, customer_id, order_date)
VALUES (order_id_seq.NEXTVAL, 101, SYSDATE);

INSERT INTO orders (order_id, customer_id, order_date)
VALUES (order_id_seq.NEXTVAL, 102, SYSDATE);

-- 获取当前会话中序列的最新值
SELECT order_id_seq.CURRVAL FROM DUAL; -- DUAL是一个虚拟表,用于执行SELECT语句

-- 删除序列
-- DROP SEQUENCE order_id_seq;

为什么我们还需要序列,而不是直接用自增列(AUTO_INCREMENT / IDENTITY)?

这确实是个好问题,很多初学者都会有这个疑问。在我看来,自增列固然方便,但序列提供了更高级别的灵活性和控制力,尤其是在一些特定场景下,它的优势就凸显出来了。

首先,序列是独立于表的。这意味着你可以用同一个序列为多个表生成主键,比如你可能有一个通用的ID生成策略,所有业务实体都从一个地方获取唯一ID。这在一些微服务架构或者需要全局唯一ID的场景下非常有用。而自增列是绑定在特定表上的,一个表一个自增,无法共享。

其次,序列可以提前获取值。有时,我们可能需要在插入数据之前就拿到这个主键值,比如在应用程序层进行一些预处理,或者将这个ID传递给其他系统。使用

NEXTVAL
可以轻松实现这一点,你甚至可以在没有真正插入数据之前就获取到一串ID。自增列的值通常是在
INSERT
操作完成后才由数据库生成并返回的。

再者,序列的并发处理能力更强。数据库系统在处理序列的

NEXTVAL
请求时,通常会以非常高效和并发安全的方式进行,它能保证在多用户同时请求时,每个用户都能拿到一个唯一的、递增的值,而不会出现冲突。虽然自增列也能保证唯一性,但在某些高并发写入场景下,序列的内部实现可能在性能上表现得更稳定或更可控。

最后,序列提供了更多的自定义选项。比如你可以控制递增步长、起始值、最大最小值,甚至是否循环。这些细粒度的控制在某些业务需求下是必不可少的,例如需要生成偶数ID、奇数ID,或者在特定范围内循环使用ID等。自增列的配置选项通常比较有限,大多只能设置起始值和递增步长。

当然,如果你只是简单地为一个表生成唯一主键,且没有其他特殊需求,那么自增列无疑是更简洁的选择。但一旦业务逻辑变得复杂,或者需要跨表、跨系统共享ID,序列的强大之处就体现出来了。

家电小商城网站源码1.0
家电小商城网站源码1.0

家电公司网站源码是一个以米拓为核心进行开发的家电商城网站模板,程序采用metinfo5.3.9 UTF8进行编码,软件包含完整栏目与数据。安装方法:解压上传到空间,访问域名进行安装,安装好后,到后台-安全与效率-数据备份还原,恢复好数据后到设置-基本信息和外观-电脑把网站名称什么的改为自己的即可。默认后台账号:admin 密码:132456注意:如本地测试中127.0.0.1无法正常使用,请换成l

下载

序列的高级选项与使用考量

序列的创建参数远不止

START WITH
INCREMENT BY
那么简单,它们各自有其存在的理由和适用场景。理解这些高级选项,能帮助我们更好地设计和优化数据库。

  • MINVALUE
    MAXVALUE
    这两个参数定义了序列的有效范围。你可能会想,为什么需要限制范围?一个常见的原因是,如果你的ID字段是
    INT
    类型,它有自己的最大值。如果序列一直递增,最终会超出这个类型的存储范围,导致溢出错误。设置
    MAXVALUE
    可以提前预警,让你在序列耗尽前采取措施。另一方面,
    MINVALUE
    在递减序列中会更有用,或者用于确保ID不会低于某个业务定义的阈值。我个人觉得,虽然大部分时候我们可能不会用到
    MINVALUE
    ,但
    MAXVALUE
    在规划长期系统时,是需要考虑的一个点。

  • CYCLE
    NO CYCLE
    CYCLE
    意味着序列达到
    MAXVALUE
    后会重新从
    MINVALUE
    开始(或者达到
    MINVALUE
    后从
    MAXVALUE
    开始,如果递减)。这在一些资源受限或者需要循环利用ID的场景下可能有用,比如一个临时的、不要求全局唯一的编号系统。但对于主键这种要求全局唯一的场景,绝对不能使用
    CYCLE
    。一旦循环,就可能生成重复的ID,这是灾难性的。所以,对于绝大多数生产环境的主键序列,我们都会明确指定
    NO CYCLE
    ,让它在达到最大值时报错,以强制我们介入处理。

  • CACHE cache_size
    NO CACHE
    这是影响序列性能和可靠性的一个关键参数。

    • CACHE cache_size
      数据库会预先在内存中生成
      cache_size
      个序列值,当应用程序请求
      NEXTVAL
      时,直接从内存中取出。这大大减少了对数据字典表的访问,显著提升了在高并发环境下的性能。我见过很多系统,在将序列从
      NO CACHE
      改为
      CACHE
      后,性能指标有了立竿见影的改善。
    • NO CACHE
      每次请求
      NEXTVAL
      时,数据库都会去更新数据字典中序列的当前值。这确保了序列值的连续性,即使服务器意外重启,也不会有值丢失。
    • 考量:
      CACHE
      的缺点是,如果数据库实例异常关闭(例如断电、崩溃),缓存中尚未使用的序列值会丢失,导致序列出现“跳号”。这些丢失的号码永远不会被使用。对于主键而言,跳号通常不是问题,因为我们只关心唯一性,不关心连续性。但如果你的业务逻辑对序列的连续性有严格要求(比如订单号要求严格连续),那么
      NO CACHE
      或者较小的
      cache_size
      可能是更稳妥的选择,尽管会牺牲一部分性能。我个人的经验是,大多数情况下,为了性能,我们都会选择
      CACHE
      ,并接受跳号的风险,因为业务通常能容忍ID不连续。

真实场景:序列的有效运用与实践

理解了序列的机制和高级选项,我们来看看它在实际工作中能解决哪些问题,以及如何有效利用。

  1. 通用主键生成器: 设想一个大型系统,有几十甚至上百张表,它们都需要一个唯一的主键。如果每张表都用

    AUTO_INCREMENT
    ,那么管理起来可能有点散。这时,创建一个或少数几个通用序列,让所有表都从这些序列中获取主键,可以统一ID的生成策略,简化开发和维护。比如,一个
    GLOBAL_ID_SEQ
    ,所有业务实体都用它。这在一些数据仓库或者需要跨表关联的场景下尤其方便。

  2. 生成业务单据编号: 订单号、发票号、流水号等,这些通常要求唯一且具有一定的可读性(比如递增)。序列是生成这类编号的理想工具。你可以结合字符串拼接,比如

    'INV-' || TO_CHAR(invoice_seq.NEXTVAL)
    来生成
    INV-0001
    INV-0002
    这样的发票号。这里的关键是,序列保证了数字部分的唯一性和递增性。

  3. 分布式系统中的ID预生成: 在一些微服务或者分布式架构中,服务A可能需要提前知道一个ID,然后将这个ID传递给服务B,服务B再用这个ID去数据库插入数据。序列的

    NEXTVAL
    可以在不实际执行
    INSERT
    语句的情况下获取ID,这为分布式事务和异步处理提供了很大的便利。

  4. 数据迁移与合并: 当你需要将来自多个源的数据库合并到一个目标数据库时,源数据库的自增ID可能会冲突。这时,可以为目标数据库创建新的序列,并在迁移过程中使用

    NEXTVAL
    为所有导入的数据生成全新的、唯一的ID,从而避免ID冲突问题。

  5. 替代数据库触发器中的复杂逻辑: 有时候,为了生成某个字段的值,我们可能会在

    INSERT
    触发器里写一些复杂的逻辑。如果这个值只是一个简单的递增数字,用序列来替代会更简洁、高效,并且更容易理解和维护。触发器虽然强大,但过度使用可能会让系统变得难以调试。

在使用序列时,一个常见的误区是过度追求“无缝连续”的ID。除非你的业务有非常严格的审计要求,否则由于事务回滚、

CACHE
机制等原因,序列出现跳号是很正常的。大部分业务场景下,我们只需要保证ID的唯一性递增趋势,而不是严格的连续性。过于执着于连续性,反而可能会牺牲性能和系统的健壮性。所以,在设计时,要权衡业务需求和技术实现之间的利弊。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

684

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

323

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

348

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1117

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

359

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

717

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

577

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

419

2024.04.29

菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 4.7万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.8万人学习

Go 教程
Go 教程

共32课时 | 4.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号