CREATE SEQUENCE — 定义一个新的序列生成器
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 } ]
CREATE SEQUENCE 创建一个新的序列号生成器。这涉及创建和初始化一个新的特殊单行表,名称为 name。该生成器将归属发出该命令的用户所有。
如果给出了架构名称,则序列将在指定的架构中创建。否则,它将在当前架构中创建。临时序列存在于一个特殊架构中,因此在创建临时序列时不能给出架构名称。序列名称必须与同一架构中的任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。
创建序列后,使用函数 nextval、currval 和 setval 对序列进行操作。这些函数在 第 9.17 节 中进行了说明。
虽然无法直接更新序列,但可以使用类似于以下内容的查询
SELECT * FROM name;
检查序列的参数和当前状态。特别是,序列的 last_value 字段显示了由任何会话分配的最后一个值。(当然,如果其他会话正在主动执行 nextval 调用,则此值可能在打印时已过时。)
TEMPORARY 或 TEMP如果指定,则仅为该会话创建序列对象,并在会话退出时自动删除。只要使用架构限定名称引用,则在临时序列存在时,具有相同名称的现有永久序列将不可见(在此会话中)。
UNLOGGED如果指定,则序列将创建为未记录序列。对未记录序列的更改不会写入预写日志。它们不是防崩溃的:未记录序列在崩溃或不干净关机后会自动重置为其初始状态。未记录序列也不会复制到备用服务器。
与未记录表不同,未记录序列不会提供显著的性能优势。此选项主要用于通过标识列或序列列与未记录表关联的序列。在这些情况下,通常没有必要对序列进行 WAL 记录和复制,但对其关联表不进行这些操作。
IF NOT EXISTS如果已存在具有相同名称的关系,则不引发错误。在这种情况下,将发出通知。请注意,无法保证现有关系与将创建的序列类似 — 它甚至可能不是序列。
name要创建的序列的名称(可选地限定架构)。
数据类型可选子句 AS 指定序列的数据类型。有效类型为 data_typesmallint、integer 和 bigint。默认值为 bigint。数据类型决定序列的默认最小值和最大值。
增量可选子句 INCREMENT BY 指定添加到当前序列值以创建新值的值。正值将生成升序序列,负值将生成降序序列。默认值为 1。increment
minvalueNO MINVALUE可选子句 MINVALUE 确定序列可以生成的最小值。如果未提供此子句或指定 minvalueNO MINVALUE,则将使用默认值。升序序列的默认值为 1。降序序列的默认值为数据类型的最小值。
maxvalueNO MAXVALUE可选子句 MAXVALUE 确定序列的最大值。如果未提供此子句或指定 maxvalueNO MAXVALUE,则将使用默认值。升序序列的默认值为数据类型的最大值。降序序列的默认值为 -1。
开始可选子句 START WITH 允许序列从任意位置开始。升序序列的默认起始值为 startminvalue,降序序列的默认起始值为 maxvalue。
缓存可选子句 CACHE 指定为加快访问速度而预先分配并存储在内存中的序列号数量。最小值为 1(一次只能生成一个值,即无缓存),这也是默认值。cache
CYCLENO CYCLECYCLE 选项允许序列在升序或降序序列分别达到 maxvalue 或 minvalue 时循环。如果达到限制,则生成的下一个数字将分别为 minvalue 或 maxvalue。
如果指定 NO CYCLE,则在序列达到其最大值后对 nextval 的任何调用都将返回错误。如果未指定 CYCLE 或 NO CYCLE,则默认值为 NO CYCLE。
OWNED BY table_name.column_nameOWNED BY NONEOWNED BY 选项导致序列与特定表列相关联,如果该列(或其整个表)被删除,则序列也将自动删除。指定表必须具有与序列相同的拥有者,并与序列位于同一模式中。 OWNED BY NONE(默认值)指定没有此类关联。
使用 DROP SEQUENCE 删除序列。
序列基于 bigint 算法,因此范围不能超出八字节整数的范围(-9223372036854775808 到 9223372036854775807)。
因为 nextval 和 setval 调用永远不会回滚,所以如果需要序列号的“无间隙”分配,则不能使用序列对象。可以通过使用包含计数器的表的独占锁定来构建无间隙分配;但此解决方案比序列对象昂贵得多,尤其是在许多事务同时需要序列号的情况下。
如果对多个会话将同时使用的序列对象使用大于 1 的 cache 设置,则可能会获得意外结果。每个会话将在对序列对象的一次访问期间分配和缓存连续的序列值,并相应地增加序列对象的 last_value。然后,在该会话中对 nextval 的下一个 cache-1 次使用只是返回预分配的值,而不触及序列对象。因此,会话中分配但未使用的任何数字都将在该会话结束时丢失,从而导致序列中出现“空洞”。
此外,虽然可以保证多个会话分配不同的序列值,但当考虑所有会话时,这些值可能会按非顺序生成。例如,如果将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不会被其他会话注意到,直到它们用尽已缓存的任何预分配值。
创建一个从 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;
CREATE SEQUENCE符合SQL标准,但有以下例外
使用nextval()函数获取下一个值,而不是标准的NEXT VALUE FOR表达式。
OWNED BY子句是PostgreSQL扩展。
如果你在文档中发现任何不正确、与你对特定功能的体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。