Oracle序列号
序列号SEQUENCE:是Oracle提供的用于产生一系列唯一数字的数据库对象。 序列号在数据库中是一个共享对象,序列号是一个计数器,它并不会与特定的表关联。 主要用于提供主键值或唯一约束值。 将序列值装入内存可以提高访问效率。 创建序列号语法: CREATE SEQUENCE [SCHEMA.]SEQUENCE_NAME [INCREMENT BY N] [START WITH N] [{MAXVALUE N | NOMAXVALUE}] [{MINVALUE N | NOMINVALUE}] [{CYCLE | NOCYCLE}] [{CACHE N | NOCACHE}]; SEQUENCE_NAME:序列号名称 INCREMENT BY用于定义序列的步长,如果省略,则默认为1,如果出现负值,则代表Oracle序列的值是按照此步长递减的。 START WITH 定义序列的初始值(即产生的第一个值),默认为1。 MAXVALUE 定义序列生成器能产生的最大值。选项NOMAXVALUE是默认选项,代表没有最大值定义,这时对于递增Oracle序列,系统能够产生的最大值是10的27次方;对于递减序列,最大值是-1。 MINVALUE定义序列生成器能产生的最小值。选项NOMAXVALUE是默认选项,代表没有最小值定义,这时对于递减序列,系统能够产生的最小值是-10的26次方;对于递增序列,最小值是1。 CYCLE和NOCYCLE 表示当序列生成器的值达到限制值后是否循环。CYCLE代表循环,NOCYCLE代表不循环。如果循环,则当递增序列达到最大值时,循环到最小值;最小值为1。对于递减序列达到最小值时,循环到最大值。如果不循环,达到限制值后,继续产生新值就会发生错误。 CACHE(缓冲)定义存放序列的内存块的大小,默认为20。NOCACHE表示不对序列进行内存缓冲。对序列进行内存缓冲,可以改善序列的性能。 缓存选项会造成数据丢失,当实例异常关闭时。 如果指定CACHE值,ORACLE就可以预先在内存里面放置一些SEQUENCE,这样存取的快些。CACHE里面的取完后,ORACLE自动再取一组到CACHE。使用CACHE或许会跳号, 比如数据库突然不正常DOWN掉(SHUTDOWN ABORT),CACHE中的SEQUENCE就会丢失。举个例子:比如你的SEQUENCE中CACHE 100,那当你SEQUENCE取到90时突然断电,那么在你重启数据库后,SEQUENCE的值将从101开始。 如果指定NOCACHE值,ORACLE就不会预先在内存里面存放SEQUENCE,当然这也就可以避免数据库不正常DOWN掉的SEQUENCE丢失。不过会产生一些问题:创建NOCACHE SEQUENCE在高并发访问时,容易导致ROW CACHE LOCK等待事件,主要原因是每次获取NEXTVAL时都需要修改ROWCACHE中的字典信息。使用NOCACHE SEQUENCE,还会导致如下问题: 由于每次修改字典信息都需要COMMIT,可能导致LOG FILE SYNC等待,NOCACHE SEQUENCE在RAC环境下,会对基于SEQUENCE生成的列创建的索引,造成实例间大量索引块争用,基于以上问题,避免创建NOCACHE SEQUENCE。 SEQUENCE相关保护机制: ROW CACHE LOCK:在调用SEQUENCE.NEXTVAL情况下需要修改数据字典时发生,对应ROW CACHE LOCK事件。 SQ LOCK:在内存缓存(并非ROW CACHE)上获取SEQUENCE.NEXTVAL时发生,对应ENQ:SQ-CONTENTION事件。 SV LOCK:RAC环境下获取CACHE+ORDER属性的SEQUENCE.NEXTVAL时发生,对应DFS LOCK HANDLE事件。 使用序列号会产生跳号,序列在下列情况下出现裂缝: 回滚 系统异常 多个表同时使用同一序列 序列号使用: -- 返回序列中下一个有效的值,任何用户都可以引用 SELECT SEQUENCE_NAME.NEXTVAL FROM DUAL; -- 序列的当前值 SELECT SEQUENCE_NAME.CURRVAL FROM DUAL; 实例应用:实现ID的自动递增 创建序列号 CREATE SEQUENCE TEST_SEQ INCREMENT BY 1 START WITH 1 MAXVALUE 30000 MINVALUE 1 CACHE 2; 创建表 CREATE TABLE TEST_TABLE( ID NUMBER(6), NAME VARCHAR2(30),courier; font-size: 14px;">CONSTRAINT PK_ID PRIMARY KEY(ID) );
插入数据 INSERT INTO TEST_TABLE VALUES(TEST_SEQ.NEXTVAL,'TOM'); COMMIT; 查看数据库中的序列号: SELECT * FROM USER_SEQUENCES; SELECT * FROM ALL_SEQUENCES; SELECT * FROM DBA_SEQUENCES; 修改序列号: ALTER SEQUENCE SEQUENCE_NAME [{CACHE N | NOCACHE}]; 不能修改序列的初始值,否则会报ORA-02283:无法更改启动序列号 删除序列号: DROP SEQUENCE [SCHEMA.]序列名; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |