Postgresql 中文操作指南
Synopsis
CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name
[ AS data_type ]
[ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table_name.column_name | NONE } ]
Description
CREATE SEQUENCE 创建一个新的序列号生成器。这涉及创建和初始化一个新的特殊单行表,名称为 name 。该生成器将归 issuing 该命令的用户所有。
如果给出了模式名称,则在指定的模式中创建序列。否则将在当前模式中创建序列。临时序列存在于特殊模式中,因此在创建临时序列时不能给出模式名称。序列名称必须不同于同一模式中任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称。
创建序列后,使用函数 nextval 、 currval 和 setval 对序列执行操作。这些函数在 Section 9.17 中有记录。
虽然不能直接更新序列,但可以使用如下查询:
SELECT * FROM name;
来检查序列的参数和当前状态。具体而言,序列的 last_value 字段显示由任何会话分配的最后一个值。(当然,如果其他会话主动执行 nextval 调用,此值在打印时可能已过期。)
Parameters
-
TEMPORARY or TEMP
-
如果指定,则仅为该会话创建序列对象,并在会话退出时自动删除。在临时序列存在期间,具有相同名称的现有永久序列不可见(在此会话中),除非它们被模式限定名称引用。
-
-
UNLOGGED
-
如果指定,则序列将创建为未记录序列。未记录序列的更改不会写入预写日志。它们不是防崩溃的:在崩溃或不正常关闭后,未记录的序列会自动重置为其初始状态。未记录的序列也不会复制到备用服务器。
-
与未记录的表不同,未记录的序列并不提供显着的性能优势。此选项主要适用于通过标识列或序列列与未记录的表关联的序列。在这些情况下,让序列 WAL 记录并复制但其关联表没有记录通常没有意义。
-
-
IF NOT EXISTS
-
如果已存在具有相同名称的关系,则不引发错误。在这种情况下,会发出通知。请注意,无法保证现有关系与应该创建的序列有相似之处,它甚至可能不是一个序列。
-
-
name
-
要创建的序列的名称(可选的模式限定)。
-
-
data_type
-
可选子句 AS _data_type_ 指定序列的数据类型。有效类型为 smallint 、 integer 和 bigint 。 bigint 是默认值。数据类型确定序列的默认最小值和最大值。
-
-
increment
-
可选子句 INCREMENT BY _increment_ 指定添加到当前序列值以创建新值的值。正值将产生升序列,负值将产生降序列。默认值是 1。
-
-
minvalue__NO MINVALUE
-
可选子句 MINVALUE _minvalue_ 确定序列可以生成的最小值。如果未提供此子句或指定 NO MINVALUE ,则将使用默认值。升序列的默认值为 1。降序列的默认值为数据类型的最小值。
-
-
maxvalue__NO MAXVALUE
-
可选子句 MAXVALUE _maxvalue_ 确定序列的最大值。如果未提供此子句或指定 NO MAXVALUE ,则将使用默认值。升序列的默认值为数据类型的最大值。降序列的默认值为 -1。
-
-
start
-
可选子句 START WITH _start_ 允许序列从任意位置开始。升序列的默认起始值为 minvalue ,降序列的默认起始值为 maxvalue 。
-
-
cache
-
可选子句 CACHE _cache_ 指定为预分配序列号并将其存储在内存中以加快访问速度。最小值为 1(一次只能生成一个值,即没有缓存),这也是默认值。
-
-
CYCLE__NO CYCLE
-
CYCLE 选项允许序列在升序列或降序列分别达到 maxvalue 或 minvalue 时环绕。如果达到限制,则生成的下一个数字将分别为 minvalue 或 maxvalue 。
-
如果指定 NO CYCLE ,则在序列达到其最大值后调用 nextval 都会返回错误。如果未指定 CYCLE 或 NO CYCLE ,则 NO CYCLE 为默认值。
-
-
OWNED BY table_name . column_name__OWNED BY NONE
-
OWNED BY 选项导致序列与特定表列关联,这样一来,如果该列(或其整个表)被删除,序列也将被自动删除。指定的表必须具有相同的拥有者,并与序列位于同一模式中。 OWNED BY NONE 是默认值,指定没有这种关联。
-
Notes
使用 DROP SEQUENCE 删除序列。
序列基于 bigint 算法,因此该范围不能超出一字节整数的范围(-9223372036854775808 至 9223372036854775807)。
因为永远不会回滚 nextval 和 setval 调用,所以如果需要序列号的“无间隔”分配,则不能使用序列对象。通过对包含计数器的表使用独占锁定可以构建无间隔分配;但是与序列对象相比,这种解决方案要昂贵得多,特别是如果许多事务需要同时使用序列号。
对于多个会话同时使用的序列对象,如果使用大于 1 的 cache 设置,可能会获得意外的结果。每个会话会在对序列对象的一次访问期间分配并缓存连续的序列值,并相应地增加序列对象的 last_value 。然后,该会话中接下来的 cache -1 次 nextval 使用只会返回预分配的值,而不会接触该序列对象。因此,会话中分配但未使用的任何数字都将在该会话结束时丢失,从而导致序列中出现“空洞”。
此外,虽然可以确保多个会话分配不同的序列值,但从所有会话考虑时这些值可能会乱序生成。例如,对于一个 cache 设置为 10,会话 A 可能会预留值 1..10 并返回 nextval =1,然后会话 B 可能会预留值 11..20 并返回 nextval =11,在会话 A 生成了 nextval =2 之前。因此,对于 cache 设置为 1,可以放心假设 nextval 值是按顺序生成的;对于 cache 设置大于 1,你应该只假设 nextval 值都是不同的,而不是完全按顺序生成的。另外, last_value 会反映任何会话预留的最新值,无论它是否已由 nextval 返回。
另一点需要注意的是,对于此类序列执行的 setval 会在其他会话用完他们已缓存的任何预分配值后,才能为其他会话注意到。
Examples
创建一个从 101 开始的升序序列,称为 serial :
CREATE SEQUENCE serial START 101;
从此序列选择下一个数字:
SELECT nextval('serial');
nextval
---------
101
从此序列选择下一个数字:
SELECT nextval('serial');
nextval
---------
102
在一个 INSERT 命令中使用此序列:
INSERT INTO distributors VALUES (nextval('serial'), 'nothing');
在一个 COPY FROM 之后更新序列值:
BEGIN;
COPY distributors FROM 'input_file';
SELECT setval('serial', max(id)) FROM distributors;
END;