序列
更新时间:2023-07-28 10:45:58
编辑
分享
序列(Sequence)是 Oracle 租户的数据库对象,可以产生不重复的有顺序的值,在表需要不重复的列做主键时很有用。本文主要介绍序列的基本特性以及 OceanBase 数据库与 Oracle 数据库序列的差异。
基本特性
序列可以提供两个伪列 CURRVAL
和 NEXTVAL
,每次查询会返回当前的序列值和下一个序列值。每当查询 NEXTVAL
都会推进 CURRVAL
值。
序列的定义里可以指定序列名、序列步长以及增序还是降序等。
CREATE SEQUENCE
语句用来创建序列,语法格式如下:
CREATE SEQUENCE sequence_name
[MINVALUE value | NOMINVALUE]
[MAXVALUE value | NOMAXVALUE]
[START WITH value]
[INCREMENT BY value]
[CACHE value | NOCACHE]
[ORDER | NOORDER]
[CYCLE | NOCYCLE];
说明
MINVALUE
和MAXVALUE
指定最小值和最大值。START WITH
指定起始值。INCREMENT BY
指定步长,可以为负数,默认是 1。CACHE
是为了性能缓存部分序列值,在并发高的时候使用。CYCLE
指定序列值是否循环。如果循环,需要指定最大值或最小值。
序列创建成功后,可以通过 USER_SEQUENCES、ALL_SEQUENCES、DBA_SEQUENCES 视图查看自己创建的序列。
ALTER SEQUENCE
语句用来修改序列的属性。序列的起始值不能修改,其他属性如最小值、最大值、步长、循环属性都可以修改。语法格式如下:
ALTER SEQUENCE sequence_name
[MINVALUE value | NOMINVALUE]
[MAXVALUE value | NOMAXVALUE]
[INCREMENT BY value]
[CACHE value | NOCACHE]
[ORDER | NOORDER]
[CYCLE | NOCYCLE];
DROP SEQUENCE
语句用来删除序列,语法格式如下:
DROP SEQUENCE sequence_name;
序列是一个独立的对象,同一个序列可以用在不同的表上。如下示例中,第一个 INSERT
语句会向表 t1
中插入 1,第二个 INSERT
语句会向表 t2
中插入 2。
CREATE SEQUENCE s1 MINVALUE 1 MAXVALUE 100 INCREMENT BY 1;
INSERT INTO t1 (id) VALUES (s1.nextval);
INSERT INTO t2 (id) VALUES (s1.nextval);
注意事项
关于 CACHE 和 ORDER
关于 CACHE
和 ORDER
,OceanBase 数据库与 Oracle 数据库序列的差异如下表所示。
模式 | Oracle 数据库 | OceanBase 数据库 |
---|---|---|
NOCACHE with ORDER | 所有 Instance 不缓存任何序列,使用时从全局 CACHE 中获取,CACHE 根据请求的先后顺序返回序列值。 | 所有 Instance 不缓存任何序列,使用时从全局 CACHE 中获取,CACHE 根据请求的先后顺序返回序列值。 |
NOCACHE with NOORDER | 所有 Instance 不缓存任何序列,使用时从全局 CACHE 中获取,CACHE 可以根据繁忙程度延迟满足一些请求,导致 NOORDER 。 | 仅语法兼容,实际效果与 NOCACHE with ORDER 相同。 |
CACHE with ORDER | 每个 Instance 都缓存相同的序列,使用之前需要通过全局锁来同步序列中的下一个可用位置。 | 仅语法兼容,实际效果与 NOCACHE with ORDER 相同。 |
CACHE with NOORDER | 每个 Instance 都缓存不同的序列,并且不需要全局同步 CACHE 状态。此时的值自然是 NOORDER 。 | 每个 Instance 都缓存不同的序列,并且不需要全局同步 CACHE 状态。此时的值自然是 NOORDER 。 |
说明
- 出于性能考虑,OceanBase 数据库建议您使用默认的
CACHE with NOORDER
方式。 - OceanBase 数据库中,不建议使用
ORDER with NO CACHE
。这种模式下,每次调用NEXTVAL
都会触发一次内部表SELECT
与UPDATE
操作,会影响数据库的性能。 - 在创建序列时,由于默认的
CACHE
值只有 20,需要手动声明一个比较大的值。对于单机 TPS 为 100 时,CACHE SIZE
建议设置为 360000。
关于 CURRVAL
在一个节点上通过 NEXTVAL
取到的序列值,不支持在另一个节点上用 CURRVAL
获得。常见于 Proxy 将 NEXTVAL
获取的语句和 CURRVAL
获取的语句发给了不同节点的情况。为了避免这个情况,可以让 NEXTVAL
取值和 CURRVAL
取值在同一个事务中,确保 Proxy 会始终把 Query 发给同一个节点。