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.column | NONE } ]
CREATE SEQUENCE 将向当前数据库里增加一个新的序列号生成器。包括创建和初始化一个新的名为 name 的单行表。生成器将被使用此命令的用户所有。
如果给出了一个模式名,那么该序列就在给定的模式中创建的。否则它会在当前模式中创建。临时序列存在于一个特殊的模式中,因此创建临时序列的时候不能给出模式名。序列名必需和同一模式中的其它序列、表、索引、视图的名字不同。
在创建序列后,你可以使用 nextval
, currval
, setval
函数操作序列。这些函数在节9.12中有详细文档。
尽管你不能直接更新一个序列,但你可以使用
SELECT * FROM name;
检查一个序列的参数和当前状态。特别是序列的 last_value 字段显示了任意后端进程最后分配的数值。当然,如果其它进程正积极地使用 nextval
,这些值在被打印出来的时候可能就已经过时了。
如果声明了这个修饰词,那么该序列对象只为这个会话创建,并且在会话结束的时候自动删除。在临时序列存在的时候,除非用模式修饰的名字引用,否则同名永久序列是不可见的(在同一会话里)。
将要创建的序列名(可以用模式修饰)
可选子句 INCREMENT BY increment 指定序列的步长。一个正数将生成一个递增的序列,一个负数将生成一个递减的序列。缺省值是 1 。
可选的子句 MINVALUE minvalue 指定序列的最小值。如果没有声明这个子句或者声明了 NO MINVALUE ,那么递增序列的缺省为 1 ,递减序列的缺省为 -263-1 。
可选的子句 MAXVALUE maxvalue 指定序列的最大值。如果没有声明这个子句或者声明了 NO MAXVALUE ,那么递增序列的缺省为 263-1 ,递减序列的缺省为 -1 。
可选的子句 START WITH start 指定序列的起点。缺省初始值对于递增序列为 minvalue ,对于递减序列为 maxvalue 。
可选的子句 CACHE cache 为快速访问而在内存里预先存储多少个序列号。最小值(也是缺省值)是 1 ,表示一次只能生成一个值,也就是说没有缓存。
CYCLE 选项可用于使序列到达 maxvalue 或 minvalue 时可循环并继续下去。也就是如果达到极限,生成的下一个数据将分别是 minvalue 或 maxvalue 。
如果声明了 NO CYCLE ,那么在序列达到其最大值之后任何对 nextval
的调用都强返回一个错误。如果既没有声明 CYCLE 也没有声明 NO CYCLE ,那么 NO CYCLE 是缺省。
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 --------- 114
在一个 INSERT 中使用此序列:
INSERT INTO distributors VALUES (nextval('serial'), 'nothing');
在一个 COPY FROM 后更新序列:
BEGIN; COPY distributors FROM 'input_file'; SELECT setval('serial', max(id)) FROM distributors; END;