欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

oracle数据库对象--序列

程序员文章站 2022-06-02 13:09:36
...

序列

通常我们在创建一个表时,都会定义一列为主键,通常是数字,对于主键我们的要求就是非空且唯一,然而在实际插入数据的时候,我们如何才能保证这个数据是唯一的呢,一种方式就是通过java代码写个工具类,产生唯一的数字,另一种方式就是今天所要介绍的第一个数据库对象–序列。

1.什么是序列?
答:序列是oracle提供的用于产生一系列唯一数字的数据库对象。

2.它有什么作用?
答:

  • 自动提供有规律且唯一的值;
  • 共享对象;
  • 通常用于表的主键的值;
  • 将序列存入内存可以提高查询效率。

3.定义序列
答:

create sequence seq_name  //序列名
increment by 增长数          //每次增长幅度
start with  起始值           //以什么数字为第一个值
maxvalue  最大值             //序列最大值
minvalue  最小值             //序列最小值
Cycle 循环 nocycle 不循环    //如果为循环使用,则到达最大值或者最小值后重新建立对象
Cache 缓存  n               //是否将序列缓存在内存中,n 代表缓存的序列个数       
//Cache<maxvalue-minvalue/increment by  代表缓存所有序列值
//创建一个序列,要求开始为1001,每次增长1,最大值为99999,最小值为1001,不缓存,不循环。
eg:create sequence emp_eid_seq increment 1 start with 1001 maxvalue 99999
 minvalue 1001 nocycle nochache 

4.使用序列
我们已经知道如何去创建序列了,那么该如何去使用我们已经创建的序列呢?
答:在使用的之前我们需要了解两个”方法”,一个是 序列名.nextval,这个可以类别我们java中的迭代器的概念,代表指向下一个序列值,而序列名.currval,则返回当前值。我们通过伪表dual,来展示一下;
select emp_eid_seq.nextval from dual; //返回结果为1001;
select emp_eid_seq.nextval from dual;//返回结果为1002; 所以seq_name.nextval 会返回下一个序列值,并将”指针“指向下一个数,如果不理解就去复习一下java迭代器概念。
select emp_eid_seq.currval from dual; //返回结果为1002,返回当前指针所指向的数值,并不移动指针。

所以和迭代器类似,如何要使用currval.必须要配合 nextval, 不然一直都会取得当前数据,我们在运用中通常用的是nextval,(移动“指针”同时取到值),切记,第一次调用序列时,必须先调用nextval,不然调用currval会报错显示“currval尚未在会话中定义”

这样我们在插入主键数据的时候就方便多了,再也不用自己想数字了,完全依靠系统帮我们自行生成。
create sequence user_id_seq increment by 1 start with 1000;
//不写最大值,默认是无穷大,但是也不会超过创建表时主键的约束,不缓存,不循环
insert into users values(user_id_seq.nextval,’小小州’,’20’);
这样就完成了一条数据的插入。

5.查询序列
查询时我们可以通过工具查看sequences文件夹,当然用命令应该更快点
select increment_by,start_with,max_value,min_value from USER_SEQUENCES;

6.修改序列
当我们想要对已经创建好的序列进行修改,我们该如何操作呢?
修改序列语法格式
ALTER SEQUENCE 序列名 INCREMENT BY x START WITH x MAXVALUE x MINVALUE x CACHE x CYCLE;

看了语法格式,发现其实就是将create关键字变成了alter,其他都不变,但是在修改一个已经创建好的序列的时候,我们需要注意几点:
1.对于已经在使用的数据,如果我们的修改将引起他的变化,那将修改不了,比如存在从1开始的,我修改start with 为2,那将是不成功的,总之,做的修改不能影响到之前的数据。一般只要使用过序列,则在修改语句中不能使用start with,不信的可以试一下。

7.删除序列
删除序列就很简单了;
drop sequence 序列名 ;
eg:drop sequence emp_id_seq;

8.裂缝
在使用序列的过程中可能会出现裂缝,也就是序列不连续了,比如本来是主键值依此应该是1,2,3,4,出现裂缝的意思就是主键值是1,3,4,5。那么是什么原因导致出现裂缝的呢,主要原因如下:
1.回滚数据导致的,我们知道可以使用rollback可以对我们刚刚插入的数据进行回滚,但是我们要知道的一点就是序列不会回滚也就是这个值我们已经使用过了,尽管现在不用了,但是虚拟指针已经指向了后面的位置了,不可能回退了,所一展现给我们的也就产生了裂缝。
2系统异常:也就是我们插入数据时候系统异常了,数据并没有插入进去, 但是序列值已经使用了,所以下次在此调用序列时就是后面一个序列了,也产生了裂缝。
多个表使用同一个序列,因为有些值在其他表显示,所以在这个表上面看就出现了裂缝。

关于cache:
之前提到的使用序列可以提高f访问效率,前提是要将序列缓存在缓存中的,也就是在创建时需要cache项的,前面也介绍了后面值代表存入的序列数,当我们应对大量序列申请请求时,为了避免序列在运用层实现序列而引起的性能瓶颈,oracle序列就允许提前生成好序列然后存入到内存中,这样当用户申请序列时,我们直接从内存中获取,提高执行效率。
在这里我们一次性缓存的数据不能太大,因为数据库重启时,会清空完所有的缓存序列,然后启动后就从上次缓存的最大值加一重新缓存,如果太大,就会使很多序列没有被使用,也就是产生前面的裂缝。
如有错误,欢迎指出。谢谢。