在许多数据库之中都会存在有一种数据类型——自动增长列,它能够创建流水号。但是非常遗憾的是,在Oracle 12C以前并没有提供这样自动的增长列,但是从Oracle 12C开始出现了自动增长列,如果要想在Oracle之中实现这样的自动增长列,那么就可以使用序列的方式完成。
如果要想使用序列,则可以采用如下的语法完成创建。
CREATE SEQUENCE 序列名称
[MAXVALUE 最大值 | NOMAXVALUE]
[MINVALUE 最小值 | NOMINVALUE]
[INCREMENT BY 步长] [START WITH 开始值]
[CYCLE | NOCYCLE]
[CACHE 缓存个数 | NOCACHE] ;
序列属于数据库对象的创建过程,属于DDL的分类范畴,对于序列而言,创建之后一定会在数据字典之中保存。
删除序列:
DROP SEQUENCE 名称
范例:创建序列
create sequence mysql;
范例:查询user_sequences数据字典
select * from user_sequences;
查询的内容是:
· SEQUENCE_NAME:序列名称,本次为MYSQL;
· MIN_VALUE:当前序列的最小值,本次为1;
· MAX_VALUE:当前序列的最大值,本次为“1.0000E+28”;
· INCREMENT_BY:每次序列增长的步长内容;
· CY:是否为循环序列,本次为“N”;
· OR:是否需要排序;
· CACHE_SIZE:缓存个数,默认为20个;
· LAST_NUMBER:最后的数值。
现在序列已经创建成功了,如果要想使用序列则可以使用如下的两个伪列完成:
· nextval:取得序列下一个内容,每一次调用序列的值都会增长;
· currval:表示取得序列的当前内容,每一次调用序列不会增长,如果要想使用此伪列,那么在使用之前必须首先使用nextval取得内容才可以
取得序列发现输出的是‘尚未在此会话中定义’
select mysql.currval from dual;
必须先取得nextval:每输出一次将会自动增长
select mysql.nextval from dual;
在调用currval序列将不会在增长
select mysql.currval from dual;
如果要想在实际开发之中使用序列进行开发操作,那么必须手工在数据增加的时候进行处理,而数据表的定义与之前没有任何的区别
create table mytab(
id number,
name varchar2(50),
constraint pk_id primary key(id)
);
此时的数据表与原始相比没有任何的区别,但是最关键的部分是在数据增加的时候,由于id属于一个主键列,所以可以利用序列来生成id的内容,执行一下语句,多执行几次。
insert into mytab(id,name)values(mysql.nextval,'HELLO');
查看mytab表,此时发现序列自动增长了
select * from mytab;
什么是缓存?缓存有什么用:
默认的缓存是20个: CACHE_SIZE:缓存个数,默认为20个, SEQUENCE_NAME:序列名称, LAST_NUMBER:最后的数值,查询user_sequences数据字典, nextval:取得序列下一个内容,每一次调用序列的值都会增长;
------------------------------------------------------------------------------------------------------------------
select mysql.nextval from dual;
select sequence_name,cache_size,last_number from user_sequences;
------------------------------------------------------------------------------------------------------------------
执行此语句一次后发现主键id是1,最后值也是1(LAST_NUMER),缓存是20(CACHE_SIZE),第二次执行发现id变成2,最后值变成21,之后在执行19次,最后值就变成41,因为缓存默认是20,所以执行20次最后值才会变化
在序列的操作过程之中,为了保证序列操作的性能问题,所以会利用缓存,在用户未使用到指定的序列值时自动的将内容创建好,这样用户在使用序列中就不是一起创建的了,从而达到性能的提升。
但是缓存本身会存在一个丢号的问题,如果数据库关闭了,那么序列的内容就可能无法连续了。称为跳号问题
1---------------------------------------------------------------------------------------------------------------------------
范例:改变序列的步长
--删除序列
drop sequence mysql;
--创建序列,此处不要加分号↓
create sequence mysql
--每次序列增长的步长2
increment by 2;
select mysql.nextval from dual;
select sequence_name,cache_size,last_number from user_sequences;
此时发现序列每次2次一加
1---------------------------------------------------------------------------------------------------------------------------
范例:改变序列的开始值,默认是1
drop sequence mysql;
--不要加分号↓
create sequence mysql
--不要加分号↓
increment by 2
--改变开始值
start with 10000;
select mysql.nextval from dual;
select sequence_name,cache_size,last_number from user_sequences;
现在发现序列是从10000开始的
2---------------------------------------------------------------------------------------------------------------------------
在序列的使用过程之中还可以创建一个循环序列的概念,例如:现在希望序列可以在1、3、5、7、9之间循环显示,所以此时就需要设置序列的最大值:9、最小值1:1、而且设置为循环。
范例:创建循环序列
drop sequence mysql;
create sequence mysql
increment by 2 start with 1
minvalue 1 maxvalue 9
cycle;
2---------------------------------------------------------------------------------------------------------------------------
输出后会报一下错:↓
ORA-04013: CACHE 值必须小于 CYCLE 值
一定要记住数据字典之中的LAST_NUMBER它的结果是缓存个数 * 步长,如果步长设置成2,缓存默认是20,步长增加20次后缓存就是40,这里的最小值是1,最大值是9,而缓存是40所以就报错。
3---------------------------------------------------------------------------------------------------------------------------
drop sequence mysql;
create sequence mysql
increment by 2 start with 1
minvalue 1 maxvalue 9
--把缓存设置成2,小于9就可以了
cycle cache 2;
3---------------------------------------------------------------------------------------------------------------------------
4---------------------------------------------------------------------------------------------------------------------------
drop sequence mysql;
create sequence mysql
increment by 2 start with 1
minvalue 1 maxvalue 9
--或者不设置缓存
cycle nocache;
select mysql.nextval from dual;
select sequence_name,cache_size,last_number from user_sequences;
4---------------------------------------------------------------------------------------------------------------------------
同义词
1---------------------------------------------------------------------------------------------------------------------------
同义词本质上来讲就属于近义词的概念。在之前使用过这样的一种查询。
select sysdate from dual;
1---------------------------------------------------------------------------------------------------------------------------
2---------------------------------------------------------------------------------------------------------------------------
dual属于一张临时表,那么这张临时表到底是属于谁的呢?
select * from tab;
select * from tab where tname='DUAL';
1、conn system/manager
select * from tab where tname='DUAL';
2、conn sys/change_on_install as sysdba;
select * from tab where tname='DUAL';
通过一系列的查询可以发现,dual数据表本身属于sys用户的
2---------------------------------------------------------------------------------------------------------------------------
既然dual属于sys,那么按照之前的概念来讲,不同的用户要进行表的互相访问,那么前面需要使用模式名,也就是说如果scott用户要使用dual,则应该使用sys.dual才对。而这个操作就属于同义词的定义范畴,也就是说dual是sys.dual的同义词。
如果要想创建同义词,则可以使用如下的语法完成。
CREATE [PUBLIC] SYNONYM 同义词名称 FOR 模式.表名称
3---------------------------------------------------------------------------------------------------------------------------
此时在sys用户下查找emp表
conn sys/change_on_install as sysdba;:
select * from emp;
发现输出是:表和视图不存在
跟上scott.emp
select * from scott.emp;
发现这样就可以查询了
3---------------------------------------------------------------------------------------------------------------------------
创建同义词
范例:将scott.emp数据表映射为semp
create synonym semp for scott.emp;
select * from semp;
换到emp表:
conn scott/tiger
select * from sys.semp;
4---------------------------------------------------------------------------------------------------------------------------
但是现在的问题是,此同义词无法被其他用户所使用,它只能够被sys所使用。
如果要想让一个同义词被所有用户去使用,那么应该创建为公共同义词
范例:切换回sys用户,重新创建同义词
conn sys/change_on_install as sysdba;
--删除同义词
drop synonym semp;
--创建为公共同义词
create public synonym semp for scott.emp;
此时虽然同义词可以被其他用户访问了,但是对我们开发的意义不大
4---------------------------------------------------------------------------------------------------------------------------
同义词了解就可以了