创建和使用序列#

序列对象(也叫序列生成器或只是序列)是特殊的单列表。一个序列对象通常用于生成表中行的唯一标识。

创建序列#

使用CREATE SEQUENCE命令创建新的序列号生成器。这涉及到创建和初始化一个新的特殊单行表。生成器将由发出命令的用户拥有。

CREATE SEQUENCE myseq START 101;

如果给定模式名称,则在指定模式中创建序列,否则将在当前模式中创建。临时序列存在于特殊模式中,因此在创建临时序列时可以不提供模式名称。序列名必须与同一模式中任何其他序列、表或视图的名称不同。

创建序列后,可使用nextval函数对序列进行操作。

INSERT INTO tbl VALUES ('seq',nextval('myseq'));

也可以使用setval函数对序列进行操作,但不能对分布式数据的查询进行操作。例如,以下查询是允许的,因为它重置Master上序列生成器进程的序列计数器值:

SELECT setval('myseq', 201);

在常规非分布式数据库中,对序列进行操作的函数会根据需要到本地序列表获取值。然而,在 OushuDB 中,每个Segment都是自己的不同数据库进程。因此,Segment需要一个唯一关键值来获取序列值,以便所有Segment正确递增,序列以正确的顺序向前移动。序列服务器进程在Master上运行,是 OushuDB 分布式数据库中序列的关键点。Segment在运行时从Master获取序列值。

由于这种分布式序列设计,在 OushuDB 中操作序列的函数有一些限制:

不支持lastval和currval函数。

setval只能用于设置master上序列生成器的值,不能用于子查询以更新分布式表数据上的记录。

nextval有时会从master中获取一个值块以供segment使用,具体取决于查询。因此,如果在segment级别不需要所有块,则有时可能会跳过序列中的值。

虽然不能直接更新序列,但可以使用以下查询:

SELECT * FROM myseq;

sequence_name | last_value | increment_by |      max_value      | min_value | cache_value | log_cnt | is_cycled | is_called
---------------+------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
 myseq         |        201 |            1 | 9223372036854775807 |         1 |           1 |       0 | f         | t

详细的序列操作请参考: 序列操作函数

使用OWNED BY可实现序列与特定的表列关联,如果该列(或其整个表)被删除,序列也将被自动删除。指定的表必须具有相同的所有者,并且与序列在同一架构中。默认情况下,OWNED BY NONE指定不存在此类关联。指定关联语句示例如下:

CREATE SEQUENCE ao_seq OWNED BY ao_tb.second_column;

总之,创建序列符合SQL标准,但有以下例外:

不支持在SQL标准中指定的 AS 数据类型表达式。

使用nextval()函数而不是SQL标准中指定的表达式的下一个值来获取下一个值。

修改序列#

当创建好的序列需要修改时,使用ALTER SEQUENCE命令,例如:

ALTER SEQUENCE myseq RESTART WITH 101;

ALTER SEQUENCE myseq INCREMENT BY 5;

SELECT nextval('myseq');

 nextval
---------
   106
(1 row)

当前修改表示myseq按照修改值101重新开始计数使用。

删除序列#

使用DROP SEQUENCE命令删除序列生成器表,且必须是序列拥有者或超级用户角色才能删除它。

DROP SEQUENCE myseq;

使用关键字CASCADE时,自动删除依赖该序列的对象;使用关键字RESTRICT时,如果有依赖要删除的序列则拒绝删除该序列。