Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

CREATE SEQUENCE

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 的特殊单行表。生成器归发出该命令的用户所有。

如果给出了架构名称,则序列在指定的架构中创建。否则,它在当前架构中创建。临时序列存在于特殊架构中,因此创建临时序列时不能给出架构名称。序列名称必须不同于同一架构中的任何其他关系名称(表、序列、索引、视图、物化视图或外部表)。

创建序列后,使用函数 nextvalcurrvalsetval 对序列进行操作。这些函数在 第 9.17 节 中记录。

虽然您无法直接更新序列,但可以使用类似如下的查询

SELECT * FROM name;

检查序列的参数和当前状态。特别是,序列的 last_value 字段显示了最后一次由任何会话分配的值。(当然,如果其他会话正在积极调用 nextval),那么在打印该值时,该值可能已过时。

参数

TEMPORARYTEMP

如果指定,则仅针对此会话创建序列对象,并且在会话退出时自动删除。在临时序列存在期间(除非使用按架构限定的名称引用),具有相同名称的现有持久序列(在此会话中)不可见。

UNLOGGED

如果指定,则序列被创建为未记录的序列。未记录的序列的更改不会写入预写式日志。它们不支持故障保护:未记录的序列在崩溃或 unclean shutdown 后会自动重置为其初始状态。未记录的序列也不会复制到备用服务器。

与未记录的表不同,未记录的序列不会提供显著的性能优势。此选项主要用于通过标识列或序列列与未记录的表关联的序列。在这些情况下,如果记录序列 WAL 并且复制序列,而未记录与其关联的表,通常是没有意义的。

IF NOT EXISTS

如果已存在具有相同名称的关系,则不抛出错误。在这种情况下,会发出通知。请注意,无法保证现有关系与即将创建的序列类似 - 甚至可能不是序列。

name

要创建的序列的名称(可以选择架构限定)。

data_type

可选子句 AS 数据类型 指定序列数据类型。有效类型为 smallintintegerbigint。默认值是 bigint。数据类型决定了序列的默认最小值和最大值。

增量

可选子句 INCREMENT BY 增量 指定要添加到当前序列值中以生成一个新值的数字。正数将产生一个递增序列,而负数则产生一个递减序列。该默认值为 1。

最小值
无最小值

可选子句 MINVALUE 最小值 决定序列可以生成的最小值。如果未提供此子句或指定了 无最小值 ,则使用默认值。对于递增序列,默认值为 1。对于递减序列,默认值为该数据类型的最小值。

最大值
无最大值

可选子句 MAXVALUE 最大值 决定序列的最大值。如果未提供此子句或指定了 无最大值 ,则使用默认值。对于递增序列,默认值为该数据类型的最大值。对于递减序列,默认值为 -1。

起点

可选子句 START WITH 起点 允许序列从任何地方开始。对于递增序列,默认起始值为 最小值,而对于递减序列,默认起始值为 最大值

缓存

可选子句 CACHE 缓存 指定要预先分配并存储在内存中以加速访问的序列数。最小值为 1(一次只能生成一个值,即无缓存),这也是默认值。

CYCLE
NO CYCLE

CYCLE 选项允许在一个递增或递减序列达到 最大值最小值 时序列进行环回。如果达到上限,则下一个生成的数字将分别是 最小值最大值

如果指定 NO CYCLE,则在序列达到其最大值后,对 nextval 的任何调用都将返回一个错误。如果没有指定 CYCLENO CYCLE,则 NO CYCLE 为默认值。

OWNED BY table_name.column_name
OWNED BY NONE

OWNED BY 选项会使该序列与特定表列相关联,因此,如果该列(或其整个表)被删除,该序列也会被自动删除。指定表必须具有与序列相同的拥有者,且必须与序列位于同一架构中。 OWNED BY NONE(默认选项)指定不存在此类关联。

注释

使用 DROP SEQUENCE 删除序列。

序列基于 bigint 算术,因此范围不能超过八字节整数的范围(-9223372036854775808 至 9223372036854775807)。

由于 nextvalsetval 调用永不回滚,因此如果需要序列号的“无缝隙”分配,就无法使用序列对象。可以通过对包含计数器的表采用独占锁定,构建无缝隙分配;但与序列对象相比,这种解决方案的成本更高,尤其在许多事务同时需要序列号的情况下。

如果对多个会话将并发使用的序列对象使用大于 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 在其他会话使用完任何预先分配的已缓存值之前,其他会话不会注意到 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 扩展。

另请参见

ALTER SEQUENCEDROP SEQUENCE