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来访问序列,就会报如下错误:

四、创建序列示例

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;

执行报错如下图:

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 ;

执行报错如下图所示:

五、使用带缓存的序列

创建序列时使用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;

执行后出错如下:

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

我们缓存设定的值是 50,而最大值是 300,那么为什么还会提示这样的信息呢? 其实我们的 cache 虽然是 50,但是我们每次增长值是 10。这样 50 次缓存提取出的数是 500 (50*10),我们每次循环的最大值是300,所以就提示我们一次获取的缓存值必须小于一次循环产生的最大值。

我们将代码修改如下:

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

发现仍然报错如下图所示:

这又是为什么呢?我们一次循环的最大值已经设置成500了,为什么还有这样的错误提示?这是因为还存在一个 minvalue ,minvalue 和 maxvalue 之间是 490 个数,也就是一次循环可以提取 490,但是我们的缓存是500。

我们将代码修改如下:

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

发现创建序列成功。在创建序列的时候关于缓存值的设置我们有一个基本的公式要求:

最大值-最小值>=(缓存值-1)*每次循环的值

只要满足这个公式的缓存值设置就没有问题。

总结:

通过上述我们发现使用序列有几个基本的约束条件,总结有以下几条:

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

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

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

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

以上是对oracle数据库的序列的详细介绍,希望能对大家理解和掌握序列的使用有所帮助。

原文地址:https://blog.51cto.com/14473726/2424530

时间: 2024-08-22 07:34:46

Oracle数据库序列详解的相关文章

Oracle数据库备份详解

Oracle数据库备份详解 Oracle官方提供多种备份方式,日常使用最多的有exp/imp常规方式,及数据泵expdp/impdp方式:下面对这两种方式进行详解. 常规方式 exp/imp imp/exp是Oracle导入导出命令,可以用作数据的迁移,expdp/imdp也是Oracle数据导入导出的命令,效率比imp/exp效率要高,这个后面再讨论 一  EXP导出命令 exp 是数据的导出命令,可以用于表,用户,整个数据库,exp -help查看帮助 Export: Release 11.

ORACLE数据库备份与恢复详解

ORACLE数据库备份与恢复详解 学习过程中的总结,有兴趣不妨看看,如果有不对的地方,高手不要留情!! Oracle的备份与恢复有三种标准的模式,大致分为两 大类,备份恢复(物理上的)以及导入导出(逻辑上的),而备份恢复又可以根据数据库的工作模式分为非归档模式(Nonarchivelog-style) 和归档模式(Archivelog-style),通常,我们把非归档模式称为冷备份,而相应的把归档模式称为热备份,他们的关系如下所示 三种方式各有优点,我们做个比较(这个是用Fireworks画的,

oracle数据库归档详解

什么是Oracle归档模式? Oracle数据库有联机重做日志,这个日志是记录对数据库所做的修改,比如插入,删除,更新数据等,对这些操作都会记录在联机重做日志里.一般数据库至少要有2个联机重做日志组.当一个联机重做日志组被写满的时候,就会发生日志切换,这时联机重做日志组2成为当前使用的日志,当联机重做日志组2写满的时候,又会发生日志切换,去写联机重做日志组1,就这样反复进行. 如果数据库处于非归档模式,联机日志在切换时就会丢弃. 而在归档模式下,当发生日志切换的时候,被切换的日志会进行归档.比如

PLSQL连接Oracle 数据库配置详解

1. 下载instantclient-basic-win32-11.2.0.1.0 (oracle官网下载地址:http://www.oracle.com/technetwork/topics/winsoft-085727.html , 下载地址2:http://download.csdn.net/detail/czw2010/5732241) 2. 解压instantclient-basic-win32-11.2.0.1.0并放置在oracle安装目录的product下(放置位置无强制要求,可

oracle 序列 详解

序列: 是oacle提供的用于产生一系列唯一数字的数据库对象. l  自动提供唯一的数值 l  共享对象 l  主要用于提供主键值 l  将序列值装入内存可以提高访问效率 创建序列: 1.  要有创建序列的权限 create sequence 或 create any sequence 2.  创建序列的语法 CREATE SEQUENCE sequence  //创建序列名称        [INCREMENT BY n]  //递增的序列值是n 如果n是正数就递增,如果是负数就递减 默认是1

ORACLE用户PROFILE详解

ORACLE用户PROFILE详解   一.官网说明 Oraclerecommends that you use the Database Resource Manager rather than the SQLstatement to establish resource limits. The Database Resource Manager offers amore flexible means of managing and tracking resource use. Purpose

Oracle执行计划详解

 简介: 本文全面详细介绍oracle执行计划的相关的概念,访问数据的存取方法,表之间的连接等内容. 并有总结和概述,便于理解与记忆! +++ 目录 --- 一.相关的概念 Rowid的概念 Recursive Sql概念 Predicate(谓词) DRiving Table(驱动表) Probed Table(被探查表) 组合索引(concatenated index) 可选择性(selectivity) 二.oracle访问数据的存取方法 1) 全表扫描(Full Table Scan

oracle rac IP详解

rac环境下vip/public/private IP的区别 每个节点要2块网卡, 3个IP,虚拟IP或者叫做业务IP,单个网卡当掉可以"漂"到其他网卡是继续提供服务 在Oracle RAC环境下,每个节点都会有多个IP地址,分别为Public/Private/Vip,这三个IP到底有啥区别呢?分别用在那些场合呢?来看看老外的回答. 1. private IP address is used only for internal clustering processing (Cache

ORACLE物化视图详解

一.物化的一般用法物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,oracle都实际上转换为视图SQL语句的查询.这样对整体查询性能的提高,并没有实质上的好处. 1.物化视图的类型ON DEMAND.ON COMMIT.二者的区别在于刷新方法的不同,ON DEMAND顾名思义,仅在该物化视图"需要"被刷新了,才进行刷新(REFRESH),即更新物化视图,以保证和基表数据的一