CREATE SEQUENCE
Name
CREATE SEQUENCE -- 定义一个新序列发生器
Synopsis
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_
的单行表。生成器将被使用此命令的用户所有。
如果给出了一个模式名,那么该序列就在给定的模式中创建的。 否则它会在当前模式中创建。临时序列存在于一个特殊的模式中, 因此创建临时序列的时候不能给出模式名。序列名必需和同一模式中的其它序列、 表、索引、视图或外表的名字不同。
在创建序列后,你可以使用nextval
、 currval
和setval
函数操作序列。 这些函数在Section 9.16中有详细文档。
尽管你不能直接更新一个序列,但你可以使用:
SELECT * FROM _name_;
检查一个序列的参数和当前状态。特别是序列的last_value
字段显示了任意会话最后分配的数值。(当然,如果其它会话正积极地使用 nextval
,这些值在被打印出来的时候可能就已经过时了。)
参数
TEMPORARY
或 TEMP
如果声明了这个修饰词,那么该序列对象只为这个会话创建, 并且在会话结束的时候自动删除。在临时序列存在的时候, 除非用模式修饰的名字引用,否则同名永久序列是不可见的(在同一会话里)。
_name_
将要创建的序列名(可以用模式修饰)
_increment_
可选子句INCREMENT BY
_increment_
指定序列的步长。 一个正数将生成一个递增的序列,一个负数将生成一个递减的序列。缺省值是 1 。
_minvalue_``NO MINVALUE
可选的子句MINVALUE
_minvalue_
指定序列的最小值。如果没有声明这个子句或者声明了NO MINVALUE
, 那么递增序列的缺省为 1 ,递减序列的缺省为-2<sup class="calibre28">63</sup>-1。
_maxvalue_
NO MAXVALUE
可选的子句MAXVALUE
_maxvalue_
指定序列的最大值。如果没有声明这个子句或者声明了NO MAXVALUE
, 那么递增序列的缺省为2<sup class="calibre28">63</sup>-1,递减序列的缺省为 -1 。
_start_
可选的子句START WITH
_start_
指定序列的起点。缺省初始值对于递增序列为_minvalue_
, 对于递减序列为_maxvalue_
。
_cache_
可选的子句CACHE
_cache_
为快速访问而在内存里预先存储多少个序列号。最小值(也是缺省值)是 1 , 表示一次只能生成一个值,也就是说没有缓存。
CYCLE
NO CYCLE
CYCLE
选项可用于使序列到达 _maxvalue_
或 _minvalue_
时可循环并继续下去。 也就是如果达到极限,生成的下一个数据将分别是 _minvalue_
或_maxvalue_
。
如果声明了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标准, 只有下面的例外:
还不支持标准的
AS <数据类型>
表达式。使用
nextval()
函数而不是标准的NEXT VALUE FOR
表达式获取下一个数值。OWNED BY
子句是PostgreSQL的扩展。