暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

oracle序列详解

元旦儿的北漂 2021-04-08
2646

什么是序列


Sequence是Oracle提供的用于产生一系列唯一数字的对象。由于oracle没有类似mysql的auto_increment设置自增列的方法。所以我们在oracle数据库中主要用序列来实现主键自增的功能。


对序列增删改查操作


  1. 创建

    • CREATE SEQUENCE sequence 创建序列名称
      [INCREMENT BY n] 递增的序列值是 n 如果 n 是正数就递增,如果是负数就递减 默认是 1
      [START WITH n] 开始的值,递增默认是 minvalue 递减是 maxvalue
      [{MAXVALUE n | NOMAXVALUE}] //最大值
      [{MINVALUE n | NOMINVALUE}] //最小值
      [{CYCLE | NOCYCLE}] //循环/不循环
      [{ORDER | NOORDER}] //排序/不排序
      [{CACHE n | NOCACHE}];//分配并存入到内存中
    • 删除

      • DROP SEQUENCE order_seq;
      • 修改

        1. 用户必须拥有ALTER ANY SEQUENCE 权限才能修改sequence. 可以alter除start以外的所有sequence参数. 如果想要改变start值,必须 drop sequence 再 create.

        2. 示例
          ALTER SEQUENCE emp_sequence INCREMENT BY 10 MAXVALUE 10000 CYCLE -- 到10000后从头开始 NOCACHE ;
        • 查询

          • --序列调用 产生一个新的序列
            select seq_test.nextval from dual
            --查看当前序列的值
            select seq_test.currval from dual
            -- 通过数据字典USER_SEQUENCES可以查看序列的设置
            SELECT SEQUENCE_NAME,MIN_VALUE,MAX_VALUE,INCREMENT_BY,LAST_NUMBER FROM USER_SEQUENCES;
            -- 查看当前用户的所有序列 
            select SEQUENCE_OWNER,SEQUENCE_NAME from dba_sequences where sequence_owner='用户名'



          序列使用过程的注意事项


          1. 序列第一次必须先调用nextval获取一个序列值才能使用currval查看当前值

          2. 序列的起始值不能小于最小值

          3. 创建一个循环序列,则必须要设定最大值

          4. 如果创建带缓存的序列,缓存的值必须满足约束公式: 最大值-最小值>=(缓存值-1)*每次循环的值

          5. CACHE(缓冲)定义存放序列的内存块的大小,默认为20。如果请求量大,为了避免序列在运用层实现序列而引起的性能瓶颈,可以适当调大缓存值。但cache个数也不能设置太大,因为在数据库重启时,会清空内存信息,预存在内存中的序列会丢失,当数据库再次启动后,序列从上次内存中最大的序列号+1 开始存入cache x个。这种情况也能会在数据库关闭时也会导致序号不连续。

          6. 如果不设置循环,可能导致序列有用尽的风险。可以日期+序列循环做主键方式避免这种问题。

          7. java开发中序列接受的对象最好不要定义为Integer。Integer.MAX_VALUE = 2147483647 = 2的32次 -1。当序列大于这个值时,Integer会截位,从而导致异常。

          8. 在数据库部署了RAC环境之后,偶尔会出现从Oracle Sequence所取出来的数是混乱的,比如第二次比第一次所取的数要小。这样当程序的逻辑依赖于ID的大小来排序时,就会产生系统混乱。

            1. 其实问题是出在数据库是个RAC环境,序列是被共享的,序列默认是有缓存的。假设RAC上的两个节点上序列缓存设为20,第一个节点上缓存1-20,第二个节点缓存了21-40,当从不同节点来进行对sequence取值的时候,从第二个节点上取的值就会比从第一个节点上取的要大。而且默认序列都是noorder的。因为很有可能出现这种情况

            2. 解决办法:①设置cache为空;②创建序列的时候设置为order,即采用cache + order



          文章转载自元旦儿的北漂,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论