受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

CREATE SEQUENCE

CREATE SEQUENCE — 定义一个新的序列发生器

Synopsis

CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name
    [ AS data_type ]
    [ INCREMENT [ BY ] increment ]
    [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
    [ [ NO ] CYCLE ]
    [ START [ WITH ] start ]
    [ CACHE cache ]
    [ OWNED BY { table_name.column_name | NONE } ]

描述

CREATE SEQUENCE创建一个新的序列号发生器。这会创建并 初始化一个名为name的特殊单行表。该发生器归发出该命令 的用户所有。

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

创建序列后,可以使用函数 nextvalcurrval以及 setval来操作该序列。这些函数的文档见 Section 9.17

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

SELECT * FROM name;

来查看序列的参数和当前状态。特别是,序列的 last_value字段会显示任一会话最近分配的值。(当然, 如果其他会话正在调用nextval,那么到该值被打印出来 时,它可能已经过时。)

参数

TEMPORARYTEMP

如果指定该项,则该序列对象只为当前会话创建,并会在会话退出时自动 删除。临时序列存在期间,已有的同名永久序列在本会话中不可见,除非 使用模式限定名来引用它们。

UNLOGGED

如果指定该项,则该序列会被创建为未记录序列。对未记录序列的更改不 会写入预写式日志。它们不是崩溃安全的:在崩溃或非正常关闭之后,未 记录序列会自动重置为其初始状态。未记录序列也不会复制到备库。

与未记录表不同,未记录序列并不会带来显著的性能优势。此选项主要用 于通过标识列或 serial 列与未记录表关联的序列。在这些情况下,只对 序列做 WAL 记录和复制、而不对其关联表这样做,通常没有意义。

IF NOT EXISTS

如果同名关系已经存在,则不抛出错误。在这种情况下会发出一个提示。 注意,这并不保证现有关系与本应创建出的序列有任何相似之处 — 它甚至可能根本不是序列。

name

要创建的序列的名称(可以是模式限定的)。

data_type

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

increment

可选子句INCREMENT BY increment指定为了 生成新值,要把哪个值加到当前序列值上。正值会创建升序序列,负值会 创建降序序列。默认值为 1。

minvalue
NO MINVALUE

可选子句MINVALUE minvalue确定序列可生成的 最小值。如果未提供此子句,或者指定了 NO MINVALUE,则使用默认值。升序序列的默认值为 1。 降序序列的默认值为该数据类型的最小值。

maxvalue
NO MAXVALUE

可选子句MAXVALUE maxvalue确定序列的最大值。 如果未提供此子句,或者指定了 NO MAXVALUE,则使用默认值。升序序列的默认值是该 数据类型的最大值。降序序列的默认值是 -1。

CYCLE
NO CYCLE

CYCLE选项允许序列在升序序列达到maxvalue、或降序序列达到minvalue时分别回绕。如果达到该限制, 下一个生成的数字将分别是minvaluemaxvalue

如果指定NO CYCLE,则当序列达到其限值后,任何对 nextval的调用都会返回错误。如果既未指定 CYCLE也未指定NO CYCLE,则 默认使用NO CYCLE

start

可选子句START WITH start 允许序列从任意值 开始。升序序列的默认起始值为minvalue,降序序列的默认起始值为 maxvalue

cache

可选子句CACHE cache指定要预分配并存储 在内存中的序列号数量,以便更快访问。最小值为 1(一次只能生成一个 值,即不使用缓存),默认值也为 1。

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 不会立刻被其他会话察觉,直到它们用完自己缓存的所有预分配值为止。

示例

创建一个名为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扩展。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。