序列管理¶
序列用来生成一系列唯一的标识,因此最常见的用途是用于为一个表自动生成主键的值。从用户的角度来说,一个序列具有以下属性:
名称
当前值
递增值,即两个相邻标识之间的间隔,可以为正整数或负整数,但不能为0
最小值
最大值
初始值
是否可以循环使用标识值
缓存标识个数
在不考虑缓存标识时,对序列的第一次调用将返回序列的初始值,第二次调用将返回初始值 + 递增值,依次类推。在此期间,序列的当前值被同步更新,始终为最近一次返回的序列标识。
属性“是否可以循环使用标识值”指定了序列溢出时系统的处理方式。如一个序列初始值为1,递增值为1,最大值为5,则在经过5次NEXTVAL调用后序列的当前值将达到最大值5。若用户继续调用NEXTVAL操作,则序列将溢出,因为序列的下一个值6已经超出了最大值限制。此时,若“是否可以循环使用标识值”为真,则系统将循环使用标识值,即返回1,否则,系统将提示序列溢出错误。
- 创建序列
用户可以通过CREATE SEQUENCE命令来创建一个新的序列,如:
CREATE SEQUENCE seq INCREMENT 1 START 1 CACHE 5;
创建了一个初始值为1,递增值为1,缓存标识个数为5的序列。上述序列使用了标识缓存,因此系统将会为每一个访问序列的会话预分配一系列连续的标识,如一个会话第一次访问序列时将缓存1到5的标识,此后若有第二个会话也访问序列,则缓存6到10的标识。由于对预分配的标识的访问只需在内存中进行,因此使用标识缓存可以大大提高访问序列的效率。
使用标识缓存的序列的行为与普通序列的行为有两点不同:
- 使用标识缓存的序列不保证生成的标识的连续性。
- 使用标识缓存的序列将可能导致一部分序列标识被跳过。这是由于用户可能没有使用完所有预分配的标识。如对于上述序列,若一个会话预分配了从1到5的5个标识,而在使用了1到3等3个标识之后会话就结束了,则4和 5两个标识就被跳过。
为创建一个序列,用户必须有在待创建序列所属模式上有CREATE权限。
- 更新序列
可以通过SETVAL函数设定序列的当前值。如:
SELECT SETVAL('seq', 2);
将序列seq的当前值设为2。在设定的当前值之后,下一次对序列的访问将返回当前值 + 递增值。但若使用标识缓存,则其它会话中已经缓存的标识不受影响。如会话1调用SETVAL将序列当前值设为2,但此时会话2已经缓存了6到10等5个标识,则会话2访问序列时仍将依次返回6, 7, 8, 9, 10等标识。
为更新一个序列,用户必须拥有待更新序列上的UPDATE权限。
- 删除序列
用户可以使用DROP SEQUENCE命令来删除一个序列,如语句:
DROP SEQUENCE seq;
将删除序列seq。
为删除一个序列,用户必须是待删除序列的拥有者或系统管理员。