设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 百科 > 正文

Oracle数据库序列详解

发布时间:2021-01-06 15:25 所属栏目:128 来源:网络整理
导读:前言: 做过web开发的人员基本上都知道,数据库表中的主键值有的时候我们会用数字类型的并且自增。这样mysql、sql server中的都可以使用工具创建表的时候很容易实现。但是oracle中没有设置自增的方法,一般情况我们会使用序列和触发器来实现主键自增的功能。

前言:

做过web开发的人员基本上都知道,数据库表中的主键值有的时候我们会用数字类型的并且自增。这样mysql、sql server中的都可以使用工具创建表的时候很容易实现。但是oracle中没有设置自增的方法,一般情况我们会使用序列和触发器来实现主键自增的功能。下面这面文章主要介绍序列。

一、什么是序列

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

二、怎么样创建序列

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

三、如何使用序列

序列创建后,可以使用序列的NEXTVAL来获取序列的下一个值,使用CURRVAL来查看当前值。第一次使用必须先使用NEXTVAL来产生一个值后才可以使用CURRVAL进行查看。

//序列调用 产生一个新的序列
select seq_test.nextval from dual
//查看当前序列的值
select seq_test.currval from dual

如果第一次直接使用CURRVAL来访问序列,就会报如下错误:

Oracle数据库序列详解

四、创建序列示例

4.1 最简单的序列示例

CREATE SEQUENCE seq_test;

执行这个创建语句会在数据库中产生一个名字为seq_test的序列对象,其它的参数都会默认使用默认值。查看生成的源码如下:

-- Create sequence 
create sequence SEQ_TEST
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
cache 20;

当你调用seq_test这个序列时,它会为你产生从1到999999999999999999999999999的连续递增数值,从1开始,每次增量为1,不循环产生。产生最大值后将无法使用。默认使用缓存生成,每次缓存的数量为20个。关于缓存我们后面再讲。

4.2 创建有最大值的非循环序列

create sequence seq_test1
increment by 1
start with 10
maxvalue 300
minvalue 5;

这个序列虽然设置最小值为5,但由于开始值为10,并且不循环产生,所以不会产生10以下的数值。需要注意的是,序列的起始值不能小于最小值,否则创建序列会报错。我们把上面代码改成如下:

create sequence seq_test1
increment by 1
start with 10
maxvalue 300
minvalue 11;

执行报错如下图:

Oracle数据库序列详解

4.3 创建有最大值的循环序列

create sequence seq_test2
increment by 1
start with 10
maxvalue 300 
minvalue 5
cycle ;

当我们执行序列提取到最大值300时,序列会从最小值5开始重新循环生成。而此序列第一次是从开始值生成。

需要注意的是,如果我们创建一个循环序列,则必须要设定最大值,否则会报错:

create sequence seq_test2
increment by 1
start with 10
minvalue 5
cycle ;

执行报错如下图所示:

Oracle数据库序列详解

五、使用带缓存的序列

创建序列时使用CACHE能提高性能,特别是在高并发的情况下对数据库的性能提升还是不错的。但是使用缓存会有产生断号的现象,如果你的业务要求序列产生的值必须是连续的,那就只能使用nocache了。

我们先来了解一下cache这个参数的作用。cache,它的用处是缓存指定个数的序列值。比如你设置的 cache 是20,那么在获取 nextval 时,Oracle 会直接从 cache 中取下一个序列值,如果 cache 中缓存的序列值没有了(比如 cache 中的序列值用完了,或者被手工清空了),那么 Oracle 会再次产生20个序列值,并放置 cache 中供使用,这样有助于提高序列值的获取速度。

我们下面通过一个案例来演示一下缓存的作用:

--创建一个带缓存的序列
create sequence SEQ_CACHE
minvalue 1
maxvalue 1000
start with 1
increment by 1
cache 20;

此时执行SEQ_CACHE.nextval 会返回产生第一个值1。调用SEQ_CACHE.currval 查看当前值为1。

当我们第一次调用nextval时,由于设置了缓存数为20,序列会一次生成20个数值放在缓存里。当我们再次调用nextval时其实是从缓存里取到的值。假如我们此时将缓存清空再调用nextval,我们来测试一下。

-- 清空 cache 中缓存的序列值
alter system flush shared_pool;
-- 再次调用nextval获取序列值
select seq_cache.nextval from dual;

发现获取的值是21而不是2 。因为缓存里的值被清空了,所以系统会自动又获取20个新的连续值放在缓存里。

我们现在再执行四次nextval,会得到当前的值为25。此时我们再次清空缓存,然后再次调用nextval来获取序列。

-- 清空 cache 中缓存的序列值
alter system flush shared_pool;
-- 再次调用nextval获取序列值
select seq_cache.nextval from dual;

我们会得到当前的值为41。为什么呢?因为每次oracle获取20值是从上次获取的最大值开始的,而不是从当前值开始计算的!使用缓存会产生产生的数字不连接的风险,如果系统出异常或oracle重启则系统会清空缓存的数据,当调用nextval时会重新获取相应缓存设置的数量的值。

我们再来看一个带缓存的案例:

create sequence SEQ_CACHE1
increment by 10
start with 10
maxvalue 300
minvalue 10
cycle
cache 50;

执行后出错如下:

Oracle数据库序列详解

为什么会出现这样的错误呢?

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读