总结几点
(1)序列适合生成唯一且连续的主键值,但是个人认为不太适合生成具有业务意义的字段,在这个业务中用生成的序列作为用户抽奖编号,以此判断用户是否中奖,具有业务意义的字段,是否用max函数去生成这个编号会更好,但是使用max函数的话会不会有并发问题。使多个用户抽到同一个编号
(2)当使用到序列的事务发生回滚。会造成序列号不连续。在用生成的序列值作为抽奖编号做插入数据库操作时,可能遇到事务提交失败,从而导致序号不连续。
(3)大量语句发生请求,申请序列时,为了避免序列在运用层实现序列而引起的性能瓶颈。Oracle序列允许将序列提前生成 cache x个先存入内存,在发生大量申请序列语句时,可直接到运行最快的内存中去得到序列。但cache个数也不能设置太大,因为在数据库重启时,会清空内存信息,预存在内存中的序列会丢失,当数据库再次启动后,序列从上次内存中最大的序列号+1 开始存入cache x个。这种情况也能会在数据库关闭时也会导致序号不连续。
下面学习下Oracle的序列
其实说起序列这个其实很简单,但是如果只不了解的话还是会在上面栽跟头。
1、Create Sequence
(注释:你需要有CREATE SEQUENCE或CREATE ANY SEQUENCE权限)
CREATE SEQUENCE SEQ_EXAMPLE
INCREMENT BY 1 —— 每次加几个
START WITH 1 —— 从几开始计数
MAXVALUE 999999999—— 最大值
NOMAXVALUE —— 不设置最大值
NOCYCLE —— 一直累加,不循环
CYCLE
CACHE 10;—— 不设置缓存大小
只要定义了 SEQ_EXAMPLE ,你就可以用使CURRVAL,NEXTVAL
CURRVAL=返回 sequence的当前值
NEXTVAL=增加sequence的值,然后返回 sequence 值
例如:
SEQ_EXAMPLE.CURRVAL
SEQ_EXAMPLE.NEXTVAL
//查询序列的当前值
select SEQ_EXAMPLE.currval from dual;
需要注意的是:
第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT BY值,然后返回增加后的值。CURRVAL 总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次SEQUENCE的值,所以如果你在同一个语句里面使用多个NEXTVAL,其值就会是不一样的。
- 假如指定CACHE值,Oracle就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,Oracle自动再取一组 到cache. 使用cache或许会跳号, 比如数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失。 所以可以在create sequence的时候用nocache防止这种情况。
2、Alter Sequence
你需要有sequence的owner,或者拥有ALTER ANY SEQUENCE 权限才能改动sequence. 可以alter除start至以外的所有sequence参数。如果想要改变start值,必须 drop sequence 再 re-create .
Alter sequence示例:
ALTER SEQUENCE emp_sequence INCREMENT BY 10 MAXVALUE 10000 CYCLE -- 到10000后从头开始 NOCACHE ;
可以影响Sequence的初始化参数:
SEQUENCE_CACHE_ENTRIES =设置能同时被cache的sequence数目。
3、Drop Sequence
DROP SEQUENCE SEQ_EXAMPLE ;