问题报告 纠错本页面

CREATE SEQUENCE

名称

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

大纲

CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ 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.16 节中有详细文档。

尽管你不能直接更新一个序列,但你可以使用:

SELECT * FROM name;

检查一个序列的参数和当前状态。特别是序列的last_value 字段显示了任意会话最后分配的数值。(当然,如果其它会话正积极地使用 nextval,这些值在被打印出来的时候可能就已经过时了。)

参数

TEMPORARYTEMP

如果声明了这个修饰词,那么该序列对象只为这个会话创建, 并且在会话结束的时候自动删除。在临时序列存在的时候, 除非用模式修饰的名字引用,否则同名永久序列是不可见的(在同一会话里)。

name

将要创建的序列名(可以用模式修饰)

increment

可选子句INCREMENT BY increment指定序列的步长。 一个正数将生成一个递增的序列,一个负数将生成一个递减的序列。缺省值是 1 。

minvalue
NO MINVALUE

可选的子句MINVALUE minvalue 指定序列的最小值。如果没有声明这个子句或者声明了NO MINVALUE, 那么递增序列的缺省为 1 ,递减序列的缺省为-263-1。

maxvalue
NO MAXVALUE

可选的子句MAXVALUE maxvalue 指定序列的最大值。如果没有声明这个子句或者声明了NO MAXVALUE, 那么递增序列的缺省为263-1,递减序列的缺省为 -1 。

start

可选的子句START WITH start 指定序列的起点。缺省初始值对于递增序列为minvalue, 对于递减序列为maxvalue

cache

可选的子句CACHE cache 为快速访问而在内存里预先存储多少个序列号。最小值(也是缺省值)是 1 , 表示一次只能生成一个值,也就是说没有缓存。

CYCLE
NO CYCLE

CYCLE选项可用于使序列到达 maxvalueminvalue时可循环并继续下去。 也就是如果达到极限,生成的下一个数据将分别是 minvaluemaxvalue

如果声明了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)。 在一些古老的平台上可能没有对八字节整数的编译器支持, 这种情况下序列使用普通的integer运算范围(-2147483648 到 +2147483647)。

如果cache大于一, 并且这个序列对象将被用于多会话并发的场合,那么可能会有不可预料的结果发生。 每个会话在每次访问序列对象的过程中都将分配并缓存随后的序列值, 并且相应增加序列对象的last_value。这样, 同一个事务中的随后的cache-1 次nextval将只是返回预先分配的数值,而不是使用序列对象。 因此,任何在会话中分配了却没有使用的数字都将在会话结束时丢失, 从而导致序列里面出现"空洞"

另外,尽管系统保证为多个会话分配独立的序列值,但是如果考虑所有会话, 那么这个数值可能会丢失顺序。比如,如果cache 为 10 ,那么会话 A 保留了 1..10 并且返回nextval=1, 然后会话 B 可能会保留 11..20 然后在会话 A 生成nextval=2 之前返回nextval=11。因此,对于 cache等于一的情况, 可以安全地假设nextval值是顺序生成的;而如果把 cache设置为大于一, 那么你只能假设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标准, 只有下面的例外:

又见

ALTER SEQUENCE, DROP SEQUENCE