PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

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 为名字的特殊的单行表。该生成器将由发出此命令的用户所拥有。

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

序列创建之后,你可以使用函数 nextval、currval 和 setval 来操作该序列。这些函数在 Section 9.17 中有介绍。

虽然不能直接更新一个序列,但你可以使用类似这样的查询:

SELECT * FROM name;

来查看序列的参数和当前状态。特别地,序列的 last_value 字段显示了任意会话所分配的最后一个值。(当然,如果有其他会话正在活跃地调用 nextval,这个值在打印出来时可能已经过时了。)

参数

TEMPORARY or TEMP

如果指定了此选项,则序列对象只为当前会话创建,并会在会话退出时被自动删除。在临时序列存在期间,当前会话将看不到与其同名的已有永久序列,除非用带模式限定的名称来引用它们。

UNLOGGED

如果指定了此选项,序列将被创建为非日志序列。对非日志序列的更改不会写入预写式日志。它们不具有崩溃安全性:在崩溃或非正常关机后,非日志序列会被自动重置为其初始状态。非日志序列也不会被复制到后备服务器。

与非日志表不同,非日志序列并不能带来显著的性能优势。此选项主要用于通过标识列或 serial 列与非日志表相关联的序列。在这些情况下,让序列被写入 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。

CYCLE
NO CYCLE

CYCLE 选项允许序列在升序或降序序列分别达到 maxvalue 或 minvalue 时循环。如果达到了限制,则下一个生成的数字将分别是 minvalue 或 maxvalue。

如果指定了 NO CYCLE,则在序列达到其最大值之后对 nextval 的任何调用都将返回错误。如果既未指定 CYCLE 也未指定 NO CYCLE,则默认为 NO CYCLE。

start

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

cache

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

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 可能在会话 A 生成 nextval=2 之前就保留了值 11..20 并返回 nextval=11。因此,当 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 的扩展。

另请参阅

ALTER SEQUENCE, DROP SEQUENCE