CREATE SEQUENCE — 定义一个新的序列生成器
CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ]name
[ ASdata_type
] [ INCREMENT [ BY ]increment
] [ MINVALUEminvalue
| NO MINVALUE ] [ MAXVALUEmaxvalue
| NO MAXVALUE ] [ START [ WITH ]start
] [ CACHEcache
] [ [ NO ] CYCLE ] [ OWNED BY {table_name
.column_name
| NONE } ]
CREATE SEQUENCE
创建一个新的序列号生成器。这涉及到创建一个新的特殊单行表,其名称为 name
并进行初始化。生成器将由发出命令的用户拥有。
如果给出了模式名称,则会在指定的模式中创建序列。否则,会在当前模式中创建序列。临时序列存在于一个特殊的模式中,因此在创建临时序列时不能给出模式名称。序列名称必须与同一模式中的任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。
创建序列后,您可以使用函数 nextval
、currval
和 setval
来操作该序列。这些函数记录在第 9.17 节中。
尽管您无法直接更新序列,但您可以使用类似以下的查询来
SELECT * FROM name
;
检查序列的参数和当前状态。特别是,序列的 last_value
字段显示任何会话分配的最后一个值。(当然,如果其他会话正在主动进行 nextval
调用,则此值在打印时可能已经过时。)
TEMPORARY
或 TEMP
如果指定,则仅为此会话创建序列对象,并在会话退出时自动删除。除非使用模式限定名称引用,否则在临时序列存在期间,具有相同名称的现有永久序列是不可见的(在此会话中)。
UNLOGGED
如果指定,则序列创建为未记录的序列。对未记录序列的更改不会写入预写式日志。它们不是崩溃安全的:在崩溃或不干净的关闭后,未记录的序列会自动重置为其初始状态。未记录的序列也不会复制到备用服务器。
与未记录的表不同,未记录的序列不提供显着的性能优势。此选项主要用于通过标识列或串行列与未记录的表关联的序列。在这些情况下,通常序列进行 WAL 日志记录和复制而不是其关联的表是没有意义的。
IF NOT EXISTS
如果已存在同名的关系,则不要抛出错误。在这种情况下会发出通知。请注意,不能保证现有关系与将要创建的序列有任何相似之处 —— 它甚至可能不是序列。
name
要创建的序列的名称(可选的模式限定)。
data_type
可选子句 AS
指定序列的数据类型。有效类型为 data_type
smallint
、integer
和 bigint
。bigint
是默认值。数据类型确定序列的默认最小值和最大值。
increment
可选子句 INCREMENT BY
指定将哪个值添加到当前序列值以创建新值。正值将创建一个递增的序列,负值将创建一个递减的序列。默认值为 1。increment
minvalue
NO MINVALUE
可选子句 MINVALUE
确定序列可以生成的最小值。如果未提供此子句或指定了 minvalue
NO MINVALUE
,则将使用默认值。递增序列的默认值为 1。递减序列的默认值是数据类型的最小值。
maxvalue
NO MAXVALUE
可选子句 MAXVALUE
确定序列的最大值。如果未提供此子句或指定了 maxvalue
NO MAXVALUE
,则将使用默认值。递增序列的默认值是数据类型的最大值。递减序列的默认值为 -1。
start
可选子句 START WITH
允许序列从任意位置开始。递增序列的默认起始值为 start
minvalue
,递减序列的默认起始值为 maxvalue
。
cache
可选子句 CACHE
指定要预先分配并在内存中存储多少序列号以便更快地访问。最小值为 1(一次只能生成一个值,即没有缓存),这也是默认值。cache
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
(默认值)指定不存在此类关联。
使用 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
在其他会话用完它们缓存的任何预分配值之前,不会被其他会话注意到。
创建一个名为 serial
的递增序列,从 101 开始
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;
CREATE SEQUENCE
符合SQL标准,但以下例外
获取下一个值是使用 nextval()
函数完成的,而不是标准的 NEXT VALUE FOR
表达式。
OWNED BY
子句是 PostgreSQL 扩展。
如果您发现文档中任何不正确、与您使用特定功能的体验不符或需要进一步澄清的地方,请使用此表单报告文档问题。