小菜鸟变身Oracle大神日记

小菜鸟变身Oracle大神日记



第一天

Oracle用户的创建

-- Create the user 
	create user student -- 用户名
	identified by "123456" --密码
	default tablespace USERS --表空间名
	temporary tablespace temp -- 临时表空间
	profile DEFAULT --数据文件
	account unlock; --账户是否解锁

上面的语句可以创建一个student用户,但是这个用户还不能登上数据库,因为没有数据库登录的权限,最少他需要一个

create session系统权限才能登录数据库

用户权限

用户权限分为系统权限和对象权限俩种

系统权限:create session 可以和数据库进行连接权限,create table、create view等具有创建数据库对象的权限。

对象权限:对表中的数据进行CRUD,拥有数据库对象权限的用户可以对所拥有的对象进行相对应的操作

数据库角色

oracle数据库角色是若干系统权限的集合,给Oracle用户进行授数据库角色,就是等于赋予该用户若干数据库系统权限。常用的数据库角色如下:

CONNECT角色:connect角色是Oracle用户的基本角色,connect权限代表着用户可以和Oracle服务器进行连接,建立session(会 话)。

RESOURCE角色:resouce角色是开发过程中常用的角色。 RESOURCE给用户提供了可以创建自己的对象,包括:表、视图、序列、过程、触发器、索引、包、类型等。

DBA角色:DBA角色是管理数据库管理员该有的角色。它拥护系统了所有权限,和给其他用户授权的权限。SYSTEM用户就具有DBA权限。

因此,在实际开发过程当中可以根据需求,把某个角色或系统权限赋予某个用户。授权语句如下:

授权

-- GRANT对象权限 on 对象 to 用户
grant select,insert,update,delete on JSQUSER to STUDENT;
-- GRANT 系统权限 to 用户
grant select an table to STUDENT;
-- GRANT 角色 to 用户
grant connect to STUDNET;-- 授予connect角色
grant resource to STUDENT;-- 授予resource角色

取消授权

-- Revoke 对象权限 on 对象 from 用户
revoke select ,insert,update,delete on JSQUSER from STUDENT;
-- Revoke 系统权限 from 用户
revoke select any table form student;
-- 	Revoke 角色(role) from 用户
revoke RESOURCE from STUDENT;

用户的其他操作

-- 修改用户信息
alter user STUDENT
	identified by ******** -- 修改密码
	account lock;-- 修改用户处于锁定或者解锁状态

SQL语句介绍

数据定义语言(DDL),包括 CREATE(创建)命令、 ALTER(修改)命令、 DROP(删除)命令等。

数据操纵语言(DML),包括 INSERT(插入)命令、 UPDATE(更新)命令、 DELETE(删除)命令、 SELECT … FOR UPDATE(查询)等。

数据查询语言(DQL),包括基本查询语句、 Order By 子句、 Group By 子句等。

事务控制语言(TCL),包括 COMMIT(提交)命令、 SAVEPOINT(保存点)命令、ROLLBACK(回滚)命令。

数据控制语言(DCL), GRANT(授权)命令、 REVOKE(撤销)命令。


第二天

创建测试用例

-- Create table
create table STUINFO
(
  stuid      VARCHAR2(11) not null,
  stuname    VARCHAR2(50) not null,
  sex        CHAR(1) not null,
  age        NUMBER(2) not null,
  classno    VARCHAR2(7) not null,
  stuaddress VARCHAR2(100) default '地址未录入',
  grade      CHAR(4) not null,
  enroldate  DATE,
  idnumber   VARCHAR2(18) default '身份证未采集' not null
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Add comments to the table 
comment on table STUINFO
  is '学生信息表';
-- Add comments to the columns 
comment on column STUINFO.stuid
  is '学号';
comment on column STUINFO.stuname
  is '学生姓名';
comment on column STUINFO.sex
  is '学生性别';
comment on column STUINFO.age
  is '学生年龄';
comment on column STUINFO.classno
  is '学生班级号';
comment on column STUINFO.stuaddress
  is '学生住址';
comment on column STUINFO.grade
  is '年级';
comment on column STUINFO.enroldate
  is '入学时间';
comment on column STUINFO.idnumber
  is '身份证号';
-- Create/Recreate primary, unique and foreign key constraints 
alter table STUINFO
  add constraint PK_STUINFO primary key (STUID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
   
  -- Create table
create table CLASS
(
  classno        VARCHAR2(7) not null,
  classname      VARCHAR2(50),
  monitorid      VARCHAR2(11),
  monitorname    VARCHAR2(50),
  headmasterid   VARCHAR2(8),
  headmastername VARCHAR2(50),
  classaddress   VARCHAR2(50),
  enterdate      DATE
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Add comments to the table 
comment on table CLASS
  is '班级信息表';
-- Add comments to the columns 
comment on column CLASS.classno
  is '班级号';
comment on column CLASS.classname
  is '班级名称';
comment on column CLASS.monitorid
  is '班长学号';
comment on column CLASS.monitorname
  is '班长姓名';
comment on column CLASS.headmasterid
  is '班主任教师号';
comment on column CLASS.headmastername
  is '班主任姓名';
comment on column CLASS.classaddress
  is '班级地址';
comment on column CLASS.enterdate
  is '录入时间';
-- Create/Recreate primary, unique and foreign key constraints 
alter table CLASS
  add constraint PK_CLASS primary key (CLASSNO)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255;
 
 
-- Create table
create table COURSE
(
  courseid   VARCHAR2(9) not null,
  schyear    VARCHAR2(4),
  term       VARCHAR2(4),
  coursename VARCHAR2(100)
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Add comments to the table 
comment on table COURSE
  is '课程表';
-- Add comments to the columns 
comment on column COURSE.courseid
  is '课程id';
comment on column COURSE.schyear
  is '学年';
comment on column COURSE.term
  is '学期';
comment on column COURSE.coursename
  is '课程名称';
-- Create/Recreate primary, unique and foreign key constraints 
alter table COURSE
  add constraint PK_COURSE primary key (COURSEID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
   
  -- Create table
create table STUCOURSE
(
  selectid   VARCHAR2(18) not null,
  stuid      VARCHAR2(11),
  courseid   VARCHAR2(9),
  schyear    VARCHAR2(4),
  term       VARCHAR2(4),
  redo       VARCHAR2(1),
  selectdate DATE
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Add comments to the table 
comment on table STUCOURSE
  is '学生选课表';
-- Add comments to the columns 
comment on column STUCOURSE.selectid
  is '选课id';
comment on column STUCOURSE.stuid
  is '学号';
comment on column STUCOURSE.courseid
  is '课程id';
comment on column STUCOURSE.schyear
  is '年度';
comment on column STUCOURSE.term
  is '学期';
comment on column STUCOURSE.redo
  is '是否重修';
comment on column STUCOURSE.selectdate
  is '选课时间';
-- Create/Recreate primary, unique and foreign key constraints 
alter table STUCOURSE
  add constraint PK_STUCOURSE primary key (SELECTID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255;
 
 
-- Create table
create table SCORE
(
  scoreid  VARCHAR2(18) not null,
  stuid    VARCHAR2(11),
  courseid VARCHAR2(9),
  score    NUMBER,
  scdate   DATE
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Add comments to the table 
comment on table SCORE
  is '学生成绩表';
-- Add comments to the columns 
comment on column SCORE.scoreid
  is '学生成绩id';
comment on column SCORE.stuid
  is '学生学号';
comment on column SCORE.courseid
  is '课程id(年度+上下学期+课程序列)';
comment on column SCORE.score
  is '成绩';
comment on column SCORE.scdate
  is '成绩录入时间';
-- Create/Recreate primary, unique and foreign key constraints 
alter table SCORE
  add constraint PK_SCORE primary key (SCOREID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );

字段数据类型

**数据类型 ** **类型解释 **
VARCHAR2(length) 字符串类型:存储可变的长度的字符串,length:是字符串的最大长度,默认不填的时候是1,最大长度不超过4000。
CHAR(length) 字符串类型:存储固定长度的字符串,length:字符串的固定长度大小,默认是1,最大长度不超过2000。
NUMBER(a,b) 数值类型:存储数值类型,可以存整数,也可以存浮点型。a代表数值的最大位数:包含小数位和小数点,b代表小数的位数。例子:number(6,2),输入123.12345,实际存入:123.12 。number(4,2),输入12312.345,实际春如:提示不能存入,超过存储的指定的精度。
DATA 时间类型:存储的是日期和时间,包括年、月、日、时、分、秒。例子:内置函数sysdate获取的就是DATA类型
TIMESTAMP 时间类型:存储的不仅是日期和时间,还包含了时区。例子:内置函数systimestamp获取的就是timestamp类型
CLOB 大字段类型:存储的是大的文本,比如:非结构化的txt文本,字段大于4000长度的字符串。
BLOB 二进制类型:存储的是二进制对象,比如图片、视频、声音等转换过来的二进制对象

创建信息表

-- Create table
create table stuinfo
(
 stuid   varchar2(11) not null,--学号:'S'+班号(7位数)+学生序号(3位数)(1)
 stuname  varchar2(50) not null,--学生姓名
 sex    char(1) not null,--性别
 age    number(2) not null,--年龄
 classno  varchar2(7) not null,--班号:'C'+年级(4位数)+班级序号(2位数)
 stuaddress varchar2(100) default '地址未录入',--地址 (2)
 grade   char(4) not null,--年级
 enroldate date,--入学时间
 idnumber  varchar2(18) default '身份证未采集' not null--身份证
)
tablespace USERS --(3)
 storage
 (
  initial 64K
  minextents 1
  maxextents unlimited
 );
-- Add comments to the table 
comment on table stuinfo --(4) -- 给字段加上注释
 is '学生信息表';
-- Add comments to the columns 
comment on column stuinfo.stuid -- (5)
 is '学号';
comment on column stuinfo.stuname
 is '学生姓名';
comment on column stuinfo.sex
 is '学生性别';
comment on column stuinfo.age
 is '学生年龄';
comment on column stuinfo.classno
 is '学生班级号';
comment on column stuinfo.stuaddress
 is '学生住址';
comment on column stuinfo.grade
 is '年级';
comment on column stuinfo.enroldate
 is '入学时间';
comment on column stuinfo.idnumber
 is '身份证号';
 
 
-- 插入数据 
 
insert into stuinfo values('0001','小一','1',20,'0913','一中东校区','2018',to_date('2018-09-01','yyyy-mm-dd'),'111110001');
insert into stuinfo values('0002','小二','2',21,'0914','一中东校区','2018',to_date('2018-09-01','yyyy-mm-dd'),'111110002');
insert into stuinfo values('0003','小三','1',22,'0915','一中东校区','2018',to_date('2018-09-01','yyyy-mm-dd'),'111110003');
insert into stuinfo values('0004','小四','2',23,'0916','一中东校区','2018',to_date('2018-09-01','yyyy-mm-dd'),'111110004');
insert into stuinfo values('0005','小五','1',24,'0917','一中东校区','2018',to_date('2018-09-01','yyyy-mm-dd'),'111110005');
insert into stuinfo values('0006','小六','2',25,'0918','一中东校区','2018',to_date('2018-09-01','yyyy-mm-dd'),'111110006');
insert into stuinfo values('0007','小七','1',26,'0919','一中东校区','2018',to_date('2018-09-01','yyyy-mm-dd'),'111110007');

代码解析:

(1)处: not null 表示学号字段(stuid)不能为空。

(2)处:default 表示字段stuaddress不填时候会默认填入‘地址未录入’值。

(3)处:表示表stuinfo存储的表空间是users,storage表示存储参数:区段(extent)一次扩展64k,最小区段数为1,最大的区段数不限制。

(4)处:comment on table 是给表名进行注释。

(5)处:comment on column 是给表字段进行注释。

给表格添加约束

-- Create/Recreate primary, unique and foreign key constraints 
alter table STUINFO
 add constraint pk_stuinfo_stuid primary key (STUID);
 --把stuid当做主键,主键字段的数据必须是唯一性的(学号是唯一的)
 
-- Create/Recreate check constraints 
alter table  STUINFO
 add constraint ch_stuinfo_age
 check (age>0 and age<=50);--给字段年龄age添加约束,学生的年龄只能0-50岁之内的
 
alter table STUINFO
 add constraint ch_stuinfo_sex
 check (sex='1' or sex='2');
 
alter table STUINFO
 add constraint ch_stuinfo_GRADE
 check (grade>='1900' and grade<='2999');

解析:前面的student是角色的名字

Oracle查询(select)

select命令结构

select *|列名|表达式 from 表名 where 条件 order by 列名

1.查询学生信息表(stuinfo)中“小四”同学的基本信息:

select t.* from STUINFO t where t.stuname = '小四';

2.查询“小四”同学的学号、班级、年级和地址:

select t.stuid,t.classno,t.stuaddress,t.grade from STUINFO t where t.stuname = '小四';

3.查询班级“0918”所有同学信息,按年龄进行升序展示:

select t.* from STUINFO t where t.classno = '0918' ORDER BY T.AGE ASC

4.查询班级“0918”所有同学信息,按年龄进行降序展示:

select t.* from stuinfo t where t.classno = '0918' order by t.age desc;

备份查询数据

备份查询数据命令结构:

create table 表名 as select 语句

1.备份学生信息表(stuinfo)的数据:

create table stuinfo_2018 as select * from .stuinfo ;
select * from stuinfo_2018;

第三天

Oracle插入

insert 命令结构:

insert into 表名(列名1,列名2,列名3.....values(1,2,3.....);

语法解析:

1、列名可以省略,当列名不填时,默认的是表中的所有列,列的顺序是按照建表的顺序进行排列的。

2、列名的数量和值的数量要一致,并且值的类型要和列的类型一一对应。

3、当表当中某些字段设置了某些约束的情况下,必须按照字段的约束来进行该值的插入,例如:学生信息表(STUINFO)当中设置有主键(主键字段是STUID),因此该字段必须具有唯一性,不能和原有的数据重复。age、stuname、calassno等字段是必填字段,因此是必须有值的。

1:向学生信息表(stuinfo)插入一条数据:

insert into STUINFO (STUID, STUNAME, SEX, AGE, CLASSNO, STUADDRESS, GRADE, ENROLDATE, IDNUMBER)
values ('SC201801005', '龙七', '1', 26, 'C201801', '福建省厦门市XXX号', '2018', to_date('01-09-2018', 'dd-mm-yyyy'),
 '3503021992XXXXXXXX');
select * from stuinfo t where t.stuid='SC201801005';

2:向学生信息表(stuinfo)插入重复数据:

insert into STUINFO (STUID, STUNAME, SEX, AGE, CLASSNO, STUADDRESS, GRADE, ENROLDATE, IDNUMBER)
values ('SC201801005', '龙七', '1', 26, 'C201801', '福建省厦门市XXX号', '2018', to_date('01-09-2018', 'dd-mm-yyyy'),
 '3503021992XXXXXXXX');

会报错,因为违反了唯一约束


insert插入一个select的结果集

在 Oracle 中,一个 INSERT 命令可以把一个select结果集一次性插入到一张表中。

语法结构为:

 INSERT INTOSELECT 子句

3.备份的表stuinfo_2018的数据一次插入表stuinfo当中:

delete from stuinfo t where t.stuid in (select b.stuid from stuinfo_2018 b );
insert into stuinfo select * from stuinfo_2018;
select * from stuinfo;

Oracle更新

update命令结构:

update 表名 set 列名1=1,列名2=2,列名3=3..... where 条件

1.更新学生“小四”的年龄和身份证信息:

update stuinfo t
  set t.age = '24', t.idnumber = '3503021994XXXXXXXX'
 where t.stuname = '小四';
commit;
select * from stuinfo t where t.stuname='小四';

update 利用另外一张表关联更新本表数据的命令结构如下:

update1 set 列名=select 列名 from2 where1.列名=2.列名) 
    where exists (select 1 from2 where1.列名=2.列名)

2.利用备份表stuinfo_2018更新回学生“小三”的年龄和身份证:

update stuinfo t
  set (age, idnumber) =
    (select age, idnumber from stuinfo_2018 b where b.stuid = t.stuid)
 where exists (select 1
     from stuinfo_2018 b
     where b.stuid = t.stuid
      and b.stuname = '小三');
      
select *from stuinfo t where t.stuname='小三';

注意:exists表示()内子查询语句返回结果不为空说明where条件成立就会执行主sql语句,如果为空就表示where条件不成立,sql语句就不会执行。not exists和exists相反,子查询语句结果为空,则表示where条件成立,执行sql语句。负责不执行。

第四天

Oracle删除

delete 命令结构

delete from 表名 where 条件

1.删除学生信息表(stuinfo)中学生“小三”的数据:

delete  from stuinfo t where t.stuname='张三';

truncate命令

​ truncate命令也是数据删除命令,他是直接把Oracle表数据一次删除的命令,truncate命令是一个DDL命令,不同于delete是DML命令。

truncate命令结构:

truncate table 表名;

2.删除学生信息备案表

truncate table stuinfo_2018;

truncate和delete都能删除表中的数据,他们的区别:

​ 1、TRUNCATE 是 DDL 命令,命令执行完就提交,删除的数据不能恢复; DELETE 命令是 DML 命令,命令执行完需提交后才能生效,删除后的数据可以通过日志文件恢复。

​ 2、如果表中的数据量较大,TRUNCATE的速度比DELETE速度快很多。

​ 3、truncate删除将重新设置表索引的初始大小,而delete不能。

​ 4、delete能够触发表上相关的delete触发器,而truncate则不会触发。

​ 5、delete删除的原理是一次一条从表中删除数据,并将删除操作当做事物记录在数据库的日志当中,以便进行数据回滚。而truncate是一次性进行数据页的删除,因此执行速度快,但是不能回滚。

​ 总结:truncate命令是属于DDL命令,一次性删除表中所有数据,并且数据不能恢复,在实际开发过程当中truncate命令慎用。

Oracle运算符

Oracle运算符有4个 ±*/

1.求2018年上学期数学的平均成绩

select a.*, b.coursename, c.stuname
 from score a, course b, stuinfo c
 where a.courseid = b.courseid
  and a.stuid = c.stuid;
  
  select b.coursename, sum(a.score) / count(1)
 from score a, course b
 where a.courseid = b.courseid
  and a.courseid = 'R20180101'
 group by b.coursename;

oracle关系运算符 AND OR NOT

2.查看2018年上学期数学成绩在85-95分之间的同学:

select a.*, b.coursename, c.stuname
 from score a, course b, stuinfo c
 where a.courseid = b.courseid
  and a.stuid = c.stuid
  and a.score >= '85'
  and a.score <= '95'

Oracle字符串连接符

Oracle中利用字符串连接符||来连接查询结果

1.字符串连接符

select '姓名:' || c.stuname || ', 课程:' || b.coursename || ', 成绩:' || a.score || '分。' as sxcj
 from score a, course b, stuinfo c
 where a.courseid = b.courseid
  and a.stuid = c.stuid

Oracle distinct

DISTINCT语法结构:

SELECT DISTINCT1,2,3... from 表名;

1.查询学生成绩表中课程“数学(2018上学期)”的所有出现的成绩,不重复

select distinct b.coursename, t.score
 from score t, course b
 where t.courseid = b.courseid
  and t.courseid = 'R20180101';

oracle 条件查询

Oracle条件查询时经常使用=、IN、LIKE、BETWEEN…AND来作为条件查询的操作符。

1.查询学生成绩表“score”中课程id为“R20180101”,成绩为“85”分的同学信息。

select t.stuid,
    t.courseid,
    t.score,
    b.stuname,
    b.sex,
    b.age,
    b.classno,
    b.grade
 from score t, stuinfo b
 where t.stuid = b.stuid
  and t.courseid = 'R20180101'
  and t.score = '85'

2.查询学生成绩表“score”中课程id为“R20180101”,成绩为“79”、“85”、“89”分的同学信息。

--利用逻辑运算符or 和条件"=" 查询
select t.stuid,
    t.courseid,
    t.score,
    b.stuname,
    b.sex,
    b.age,
    b.classno,
    b.grade
 from score t, stuinfo b
 where t.stuid = b.stuid
  and t.courseid = 'R20180101'
  and (t.score = '85' or t.score ='89' or t.score ='79');
-- 利用Oracle操作符”IN“查询 
select t.stuid,
    t.courseid,
    t.score,
    b.stuname,
    b.sex,
    b.age,
    b.classno,
    b.grade
 from score t, stuinfo b
 where t.stuid = b.stuid
  and t.courseid = 'R20180101'
  and t.score in ('85','89','79');

3.查询学生成绩表“score”中课程id为“R20180101”,成绩在70-95之间的学生信息。

select t.stuid,
    t.courseid,
    t.score,
    b.stuname,
    b.sex,
    b.age,
    b.classno,
    b.grade
 from score t, stuinfo b
 where t.stuid = b.stuid
  and t.courseid = 'R20180101'
  and t.score between '70' and '95'

4.查询学生基本信息表“STUINFO”中姓“张”的学生基本信息:

select * from STUINFO t where t.stuname like '张%';

5.查询学生基本信息表“STUINFO”中姓“张”的,并且姓名长度是两个字的学生基本信息:

select * from STUINFO t where t.stuname like '张_';

oracle集合运算

Oracle集合运算就是把多个查询结果组合成一个查询结果,oralce的集合运算包括:INTERSECT(交集)、UINION ALL(交集重复)、UINION(交集不重复)、MINUS(补集)。

1、INTERSECT(交集),返回两个查询共有的记录。

2、UNION ALL(并集重复),返回各个查询的所有记录,包括重复记录。

3、UNION(并集不重复),返回各个查询的所有记录,不包括重复记录 (重复的记录只取一条)。

4、MINUS(补集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录。

当我们使用Oracle集合运算时,要注意每个独立查询的字段名的列名尽量一致(列名不同时,取第一个查询的列名)、列的数据类型、列的个数要一致,不然会报错。

1.INTERSECT(交集):

select * from stuinfo 
intersect
select * from stuinfo_2018;

2.UNION ALL(并集重复)

select * from stuinfo 
union all
select * from stuinfo_2018;

3.UNION(并集不重复)

select * from stuinfo 
union
select * from stuinfo_2018;

4.MINUS(补集)

select * from stuinfo 
minus
select * from stuinfo_2018;

Oracle连接查询

Oracle连接查询,包含内关联(inner jion )和外关联(outer join),其中外关联又分为左外关联(left outer join)、右外关联(right outer join)和全外关联(full outer join)其中外关联可以使用(+)来表示。

内连接

Oracle内连接:两张表通过某个字段进行内关联,查询结果是通过该字段按关系运算符匹配出的数据行。其中可以包括:

1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列。

2、不等连接:在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值,这些关系运算符包括>、>=、<=、!>、!<、<>。

1.查询学生信息表(stuinfo)的学生信息,关联查询该学生的班级信息(class)。

select a.stuid,
    a.stuname,
    a.classno,
    b.classno,
    b.classname,
    b.monitorid,
    b.monitorname,
    b.classaddress
 from stuinfo a, class b
 where a.classno = b.classno;

外连接

外连接,返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接或左连接))、右表(右外连接或右连接)或两个边接表(全外连接)中的所有数据行。

1、left join(左联接)等价于(left outer join)返回包括左表中的所有记录和右表中联结字段相等的记录。

2、right join(右联接)等价于(right outer join)返回包括右表中的所有记录和左表中联结字段相等的记录。

3、full join (全连接)等价于(full outer join)查询结果等于左外连接和右外连接的和。

2.left join(左联接)

--左外连接(stuinfo表中数据都存在,stuinfo_2018不在stuinfo中存在的学生相关字段为null值)
select a.*, b.stuid, b.stuname
 from stuinfo a
 left join stuinfo_2018 b
  on a.stuid = b.stuid;
--左外连接(利用(+)在右边)另外一种写法
select a.*, b.stuid, b.stuname
 from stuinfo a,stuinfo_2018 b 
 where a.stuid=b.stuid(+);

3.right join(右连接)

--右外连接(stuinfo_2018表中数据都存在,stuinfo不在stuinfo_2018存在的学生相关字段为null值)
select a.*, b.stuid, b.stuname
 from stuinfo a
 right join stuinfo_2018 b
  on a.stuid = b.stuid;
--右外连接(利用(+)在左边)另外一种写法
select a.*, b.stuid, b.stuname
 from stuinfo a,stuinfo_2018 b 
 where a.stuid(+)=b.stuid;

4.full join(全外连接)

 --(全外连接(stuinfo、stuinfo_2018表中数据都存在,
 --stuinfo不在stuinfo_2018存在的学生相关字段为null值,
 --stuinfo_2018不在stuinfo存在的学生相关字段为null值)
select a.*, b.stuid, b.stuname
 from stuinfo a
 full join stuinfo_2018 b
  on a.stuid = b.stuid;

Oracle伪列

Oracle的伪列是Oracle表在存储的过程中或查询的过程中,表会有一些附加列,称为伪列。伪列就像表中的字段一样,但是表中并不存储。伪列只能查询,不能增删改。Oracle的伪列有:rowid、rownum。

ORACLE ROWID

Oracle表中的每一行在数据文件中都有一个物理地址, ROWID 伪列返回的就是该行的物理地址。使用 ROWID 可以快速的定位表中的某一行。 ROWID 值可以唯一的标识表中的一行。通过Oracle select 查询出来的ROWID,返回的就是该行数据的物理地址。

ROWID代码:

select t.*,t.rowid from stuinfo t ;
select t.*,t.rowid from stuinfo t where t.rowid='AAAShjAAEAAAAEFAAD';

ORACLE ROWNUM

ORACLE ROWNUM表示的Oracle查询结果集的顺序,ROWNUM为每个查询结果集的行标识一个行号,第一行返回1,第二行返回2,依次顺序递增。

ROWNUM 与 ROWID 不同, ROWID 是插入记录时生成, ROWNUM 是查询数据时生成。ROWID 标识的是行的物理地址。 ROWNUM 标识的是查询结果中的行的次序。

ROWNUM代码:

select t.stuid,t.stuname,t.sex,t.classno,t.stuaddress ,rownum from stuinfo t ;

ROWNUM经常用来限制查询的结果返回的行数,求前几行或前几名的数据。

1.返回学生信息表中(stuinfo)中学生年龄最低的前四位同学。

select * from (select t.stuid, t.stuname, t.sex, t.classno, t.stuaddress, t.age, rownum
 from stuinfo t
 order by t.age asc) where rownum <=4;

oracle 函数

Oracle SQL中经常使用到Oracle自带的函数,这些函数丰富了SQL的语言功能,为Oracle SQL提供了更多的操作性。Oracle函数可以接受零个或者多个输入参数,并返回一个输出结果。 Oracle 数据库中主要使用两种类型的函数:

1、单行函数:对每一个函数应用在表的记录中时,只能输入一行中的列值作为输入参数(或常数),并且返回一个结果。

例如1:MOD(X,Y) 是求余函数,返回的X除以Y的余数,其中X和Y可以是列值,也可以是常数。

例如2:TO_CHAR(X,‘YYYYMMDD’)是时间类型转字符串的函数,其中X可以是行中某一时间类型(date)的列,也可以是一个时间类型的常数。

常用的单行函数大致以下几类:

  • 字符串函数:对字符串进行操作,例如:TO_CHAR()、SUBSTR()、DECODE()等等。
  • 数值函数:对数值进行计算或操作,返回一个数字。例如:ABS()、MOD()、ROUND()等等。
  • 转换函数:将一种数据类型转换成另外一种类型:例如:TO_CHAR()、TO_NUMBER()、TO_DATE()等等。
  • 日期函数:对时间和日期进行操作的函数。例如:TRUNC()、SYSDATE()、ADD_MONTHS()等等。

2、聚合函数:聚合函数同时可以对多行数据进行操作,并返回一个结果。比如 SUM(x)返回结果集中 x 列的总合。

oracle字符型函数

**函数 ** **说明 ** **案例 ** **结果 **
ASCII(X) 求字符X的ASCII码 select ASCII(‘A’) FROM DUAL; 65
CHR(X) 求ASCII码对应的字符 select CHR(65) FROM DUAL; ‘A’
LENGTH(X) 求字符串X的长度 select LENGTH(‘ORACLE技术圈’)from DUAL; 9
CONCATA(X,Y) 返回连接两个字符串X和Y的结果 select CONCAT(‘ORACLE’,‘技术圈’) from DUAL; ORACLE技术圈
INSTR(X,Y[,START]) 查找字符串X中字符串Y的位置,可以指定从Start位置开始搜索,不填默认从头开始 SELECT INSTR(‘ORACLE技术圈’,‘技术’) FROM DUAL; 7
LOWER(X) 把字符串X中大写字母转换为小写 SELECT LOWER(‘ORACLE技术圈’) FROM DUAL; oracle技术圈
UPPER(X) 把字符串X中小写字母转换为大写 SELECT UPPER(‘Oracle技术圈’) FROM DUAL; ORACLE技术圈
INITCAP(X) 把字符串X中所有单词首字母转换为大写,其余小写。 SELECT INITCAP('ORACLE is good ') FROM DUAL; Oracle Is Good
LTRIM(X[,Y]) 去掉字符串X左边的Y字符串,Y不填时,默认的是字符串X左边去空格 SELECT LTRIM(’–ORACLE技术圈’,’-’) FROM DUAL; ORACLE技术圈
RTRIM(X[,Y]) 去掉字符串X右边的Y字符串,Y不填时,默认的是字符串X右边去空格 SELECT RTRIM(‘ORACLE技术圈–’,’-’) FROM DUAL; ORACLE技术圈
TRIM(X[,Y]) 去掉字符串X两边的Y字符串,Y不填时,默认的是字符串X左右去空格 SELECT TRIM(’–ORACLE技术圈–’,’-’) FROM DUAL; ORACLE技术圈
REPLACE(X,old,new) 查找字符串X中old字符,并利用new字符替换 SELECT REPLACE(‘ORACLE技术圈’,‘技术圈’,‘技术交流’) FROM DUAL; ORACLE技术交流
SUBSTR(X,start[,length]) 截取字符串X,从start位置(其中start是从1开始)开始截取长度为length的字符串,length不填默认为截取到字符串X末尾 SELECT SUBSTR(‘ORACLE技术圈’,1,6) FROM DUAL; ORACLE
RPAD(X,length[,Y]) 对字符串X进行右补字符Y使字符串长度达到length长度 SELECT RPAD(‘ORACLE’,9,’-’) from DUAL; ORACLE—
LPAD(X,length[,Y]) 对字符串X进行左补字符Y使字符串长度达到length长度 SELECT LPAD(‘ORACLE’,9,’-’) from DUAL; —ORACLE

oracle日期型函数

Oracle日期类型函数是操作日期、时间类型的相关数据,返回日期时间类型或数字类型结果,常用的函数有:SYSDATE()、ADD_MONTHS()、LAST_DAY()、TRUNC()、ROUND()等等。

系统日期、时间函数

**SYSDATE函数:**该函数没有参数,可以得到系统的当前时间。

案例代码:

select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

**SYSTIMESTAMP函数:**该函数没有参数,可以得到系统的当前时间,该时间包含时区信息,精确到微秒。

案例代码:

select systimestamp from dual;

**DBTIMEZONE函数:**该函数没有输入参数,返回数据库时区。

案例代码:

select dbtimezone from dual;

**ADD_MONTHS(r,n)函数:**该函数返回在指定日期r上加上一个月份数n后的日期。其中

r:指定的日期。

n:要增加的月份数,如果N为负数,则表示减去的月份数。

案例代码:

select to_char(add_months(to_date('2018-11-12','yyyy-mm-dd'),1),'yyyy-mm-dd'),
    to_char(add_months(to_date('2018-10-31','yyyy-mm-dd'),1),'yyyy-mm-dd'),
    to_char(add_months(to_date('2018-09-30','yyyy-mm-dd'),1),'yyyy-mm-dd')    
 from dual;

结果:(如果指定的日期是月份的最后一天,返回的也是新的月份的最后一天,如果新的月份比指定的月份日期少,将会自动调回有效日期)

**LAST_DAY®函数:**返回指定r日期的当前月份的最后一天日期。

案例代码:

 select last_day(sysdate) from dual;

**NEXT_DAY(r,c)函数:**返回指定R日期的后一周的与r日期字符(c:表示星期几)对应的日期。

案例代码:

 select next_day(to_date('2018-11-12','yyyy-mm-dd'),'星期四') from dual;

**EXTRACT(time)函数:**返回指定time时间当中的年、月、日、分等日期部分。

案例代码:

select extract( year from timestamp '2018-11-12 15:36:01') as year,
    extract( month from timestamp '2018-11-12 15:36:01') as month,    
    extract( day from timestamp '2018-11-12 15:36:01') as day, 
    extract( minute from timestamp '2018-11-12 15:36:01') as minute,
    extract( second from timestamp '2018-11-12 15:36:01') as second
 from dual;

**MONTHS_BETWEEN(r1,r2)函数:**该函数返回r1日期和r2日期直接的月份。当r1>r2时,返回的是正数,假如r1和r2是不同月的同一天,则返回的是整数,否则返回的小数。当r1

案例代码:

select months_between(to_date('2018-11-12', 'yyyy-mm-dd'),
           to_date('2017-11-12', 'yyyy-mm-dd')) as zs, --整数
    months_between(to_date('2018-11-12', 'yyyy-mm-dd'),
           to_date('2017-10-11', 'yyyy-mm-dd')) as xs, --小数
    months_between(to_date('2017-11-12', 'yyyy-mm-dd'),
           to_date('2018-10-12', 'yyyy-mm-dd')) as fs --负数
 from dual;

**ROUND(r[,f])函数:**将日期r按f的格式进行四舍五入。如果f不填,则四舍五入到最近的一天。

案例代码:

select sysdate, --当前时间
    round(sysdate, 'yyyy') as year, --按年
    round(sysdate, 'mm') as month, --按月
    round(sysdate, 'dd') as day, --按天
    round(sysdate) as mr_day, --默认不填按天
    round(sysdate, 'hh24') as hour --按小时
 from dual;

**TRUNC(r[,f])函数:**将日期r按f的格式进行截取。如果f不填,则截取到当前的日期。

案例代码:

select sysdate, --当前时间
    trunc(sysdate, 'yyyy') as year, --按年
    trunc(sysdate, 'mm') as month, --按月
    trunc(sysdate, 'dd') as day, --按天
    trunc(sysdate) as mr_day, --默认不填按天
    trunc(sysdate, 'hh24') as hour --按小时
 from dual;

oracle 数值型函数

**函数 ** **解释 ** **案例 ** **结果 **
ABS(X) 求数值X的绝对值 select abs(-9) from dual; 9
COS(X) 求数值X的余弦 select cos(1) from dual; 0.54030230586814
ACOS(X) 求数值X的反余弦 select acos(1) from dual; 0
CEIL(X) 求大于或等于数值X的最小值 select ceil(7.8) from dual; 8
FLOOR(X) 求小于或等于数值X的最大值 select floor(7.8) from dual; 7
log(x,y) 求x为底y的对数 select log(2,8) from dual; 3
mod(x,y) 求x除以y的余数 select mod(13,4) from dual; 1
power(x,y) 求x的y次幂 select power(2,4) from dual; 16
sqrt(x) 求x的平方根 select sqrt(16) from dual; 4
round(x[,y]) 求数值x在y位进行四舍五入。y不填时,默认为y=0;当y>0时,是四舍五入到小数点右边y位。当y<0时,是四舍五入到小数点左边|y|位。 select round(7.816, 2), round(7.816), round(76.816, -1) from dual; 7.82 / 8 / 80
trunc(x[,y]) 求数值x在y位进行直接截取y不填时,默认为y=0;当y>0时,是截取到小数点右边y位。当y<0时,是截取到小数点左边|y|位。 select trunc(7.816, 2), trunc(7.816), trunc(76.816, -1) from dual; 7.81 / 7 / 70

oracle 转换函数

**函数 ** **解释 ** **案例 ** **结果 **
asciistr(x) 把字符串x转换为数据库字符集对应的ASCII值 select asciistr(‘Oracle技术圈’) from dual; Oracle\6280\672F\5708
bin_to_num(x1[x2…]) 把二进制数值转换为对应的十进制数值 select bin_to_num(1,0,0) from dual; 4
cast(x as type) 数据类型转换函数,该函数可以把x转换为对应的type的数据类型,基本上用于数字,字符,时间类型安装数据库规则进行互转, select cast(‘123’ as number) num,cast(123 as varchar2(3)) as ch,cast(to_date(‘20181112’,‘yyyymmdd’) as varchar2(12)) as time from dual; 123/‘123’/12-11月-18(三列值,用"/"隔开)
convert(x,d_chset[,r_chset]) 字符串在字符集间的转换函数,对字符串x按照原字符集r_chset转换为目标字符集d_chset,当r_chset不填时,默认选择数据库服务器字符集。 select CONVERT(‘oracle技术圈’,‘US7ASCII’,‘ZHS16GBK’) from dual; oracle???
to_char(x[,f]) 把字符串或时间类型x按格式f进行格式化转换为字符串。 select to_char(123.46,‘999.9’) from dual; select to_char(sysdate,‘yyyy-mm-dd’) from dual; 123.52018-11-13
to_date(x[,f]) 可以把字符串x按照格式f进行格式化转换为时间类型结果。 select to_date(‘2018-11-13’,‘yyyy-mm-dd’) from dual; 2018/11/13
to_number(x[,f]) 可以把字符串x按照格式f进行格式化转换为数值类型结果。 select to_number(‘123.74’,‘999.99’) from dual 123.74

**提醒:**其中数值的格式f可以参考下表:

**参数 ** **示例 ** **说明 **
9 999 指定位置返回数字
. 99.9 指定小数点的位置
99,9 指定位置返回一个逗号
$ $99.9 指定开头返回一个美元符号
EEEE 9.99EEEE 指定科学计数法

oracle 聚合函数

Oracle聚合函数同时可以对多行数据进行操作,并返回一个结果。比如经常用来计算一些分组数据的总和和平均值之类,常用函数有AVG()、SUM()、MIN()、MAX()等等。

AVG函数

AVG([distinct ] expr):该函数可以求列或列组成的表达式expr的平均值,返回的是数值类型。其中distinct是可选参数,表示是否去掉重复行。

1.求学生信息表(stuinfo)中学生的平均年龄,代码如下:

select * from stuinfo;
select avg(t.age) from stuinfo t;

2.按照班级求各班学生的平均年龄(其中年龄大于等于30岁的不计入在内)。代码:

select classno, avg(t.age)
 from stuinfo t
 where t.age < 30
 group by t.classno;

COUNT函数

count(|[distinct]expr)函数可以用来计算查询结果的条数或行数。函数中必须指定列名或者表达式expr,不然就要全选使用号。

3.查询学生信息表中所有的学生的个数。代码如下:

select count(*) from stuinfo;

MAX

MAX([distinct] expr)、MIN([distinct] expr)函数可以返回指定列或列组成的表达式expr中的最大值或最小值。该函数也通常和where条件、group by分组结合在一起使用。

4.求学生信息表中年龄最大的学生的年龄:

select max(age) from stuinfo;

SUM

SUM([distinct] expr)函数可以对指定列或列组成的表达式expr进行求和,假如不使用分组group by ,那就是按照整表作为一个分组。

5.正好利用sum函数求和乘以人数进行求学生的平均年龄

select classno, sum(age), count(*), sum(age) / count(*), avg(age)
 from stuinfo t
 where t.age < 30
 group by t.classno;

oracle子查询

Oracle子查询就是嵌套查询,他把select 查询的结果作为另外一个select、update或delete语句的条件,它的本质就是where条件查询中的一个条件表达式。其中我们数据库开发过程中,子查询可以根据查询结果的行数的多少,可以区分为单行子查询和多行子查询。

1、单行子查询:向外部返回的结果为空或者返回一行。

2、多行子查询:向外部返回的结果为空、一行、或者多行。

Oracle单行子查询

Oracle单行子查询是利用where条件“=”关联查询结果的,如果单行子查询返回多行会报单行子查询不能返回多行的数据库错误,下面利用案例讲解子查询。

1、查询学生信息表(stuinfo)和班级表(class)中班级为“信息科学2班(18)”的所有学生信息

select *
 from stuinfo t
 where t.classno in (select b.classno
            from class b
           where b.classname = '信息科学2班(18)');
           
 /*虽然在这利用内关联也可以查出结果,
 而且效率更好,但是在一些没有关联关
 系的时候可以利用子查询 */
select t.*
 from stuinfo t, class b
 where t.classno = b.classno
  and b.classname = '信息科学2班(18)';

Oracle多行子查询

Oracle多行子查询则需要利用IN关键字来接收子查询的多行结果。也可以用量化关键字ANY、ALL和关系运算符>、>=、=、<、<=来组合使用。

ANY关键字:表示子查询结果当中的任意一个。假如:>ANY(子查询),表示:只要大于子查询当中的任意一个值,这个条件就满足。

ALL关键字:表示子查询中的所有结果。假如:>ALL(子查询),表示:必须大于子查询当中的所有结果才能满足这个条件。

2、查询班级表中所有班级的学生信息。代码如下:

select * from stuinfo t where t.classno in (select b.classno from class b);

3、ANY/ALL关键字案例展示,代码如下:

--年龄只要大于当中子查询的最小值26岁即可
select * from stuinfo t where t.age>any(26,27,28);
--年龄必须大于子查询当中的最大值28岁才可以
select * from stuinfo t where t.age>all(26,27,28);

第五天

ORACLE序列

Oracle序列Sequence是用来生成连续的整数数据的对象,它经常用来作为业务中无规则的主键。Oracle序列可以是升序列也可以是降序列。

创建Oracle序列的语法结构如下:

CREATE SEQUENCE sequence_name
[MAXVALUE num|NOMAXVALUE]
[MINVALUE num|NOMINVALUE]
[START WITH num]
[INCREMENT BY increment]
[CYCLE|NOCYCLE]
[CACHE num|NOCACHE]

语法解析:

1、MAXVALUE/MINVALUE:指定的是序列的最大值和最小值。

2、NOMAXVALUE/NOMINVALUE:不指定序列的最大值和最小值,使用系统的默认选项,升序的最大值:1027次方,降序是-1。升序最小值:1,降序的最小值:-1026。

3、START WITH:指定从某一个整数开始,升序默认是1,降序默认是-1。

4、CYCLE | NOCYCLE:表示序列达到最大值或者最小值的时候,是否重新开始。CYCLE:重新开始,NOCYCLE:不重新开始。

5、CACHE:使用 CACHE 选项时,该序列会根据序列规则预生成一组序列号。保留在内存中,当使用下一个序列号时,可以更快的响应。当内存中的序列号用完时,系统再生成一组新的序列号,并保存在缓存中,这样可以提高生成序列号的效率 。

6、NOCACHE:不预先在内存中生成序列号。

ORACLE视图

oracle视图可以理解为数据库中一张虚拟的表,他是通过一张或者多张基表进行关联查询后组成一个虚拟的逻辑表。查询视图,本质上是对表进行关联查询。

视图的本身是不包含任何数据,只是一个查询结果,当基表的数据发生变化时,视图里面的数据也会跟着发生变化。我们经常在实际开发过程中遇到的视图可以大概分为三种:单表视图、多表关联视图、视图中含有子视图

视图的作用和优势

既然视图在实际开发过程当中被广泛使用到,它到底有哪些作用和优势呢?

1、使数据简单化:可以将复杂的查询创建成视图,提供给他人使用,他人就不需要去理解其中复杂性的业务关系或逻辑关系。这样对视图的使用人员来说,就简化了数据的,屏蔽了数据的复杂性。

**2、表结构设计的补充:**系统刚刚开始设计时,大部分程序是直接访问表结构的数据的,但是随着业务的变化、系统的更新等,造成了某些表结构的不适用,这时候去修改表结构对系统的影响太大,开发成本较高,这个时候可以创建视图来对表结构的设计进行补充,降低开发成本。程序可以直接通过查询视图得到想要的数据。

**3、增加安全性:**视图可以把表中指定的字段展示给用户,而不必把表中所有字段一起展示给用户。在实际开发中,视图经常作为数据的提供方式,设置为只读权限提供给第三方人员进行查询使用。

创建视图的语法结构如下:

CREATE [OR REPLACE] VIEW view_name
AS
SELECT查询
[WITH READ ONLY CONSTRAINT]

解释:

1、OR REPLACE:如果视图已经存在,则替换旧视图。

2、WITH READ ONLY:默认不填的,用户是可以通过视图对基表执行增删改操作,但是有很多在基表上的限制(比如:基表中某列不能为空,但是该列没有出现在视图中,则不能通过视图执行 insert 操作,或者基表设置了某些约束,这时候插入视图或者修改视图的值,有可能会报错), WITH READ ONLY 说明视图是只读视图,不能通过该视图进行增删改操作。但是在现实开发中,基本上不通过视图对表中的数据进行增删改操作。

1.利用学生信息表(stuinfo)、班级表(class)关联创建视图,只提供一些学生基本信息和班级信息(剔除学生一些敏感信息:如身份证,家庭地址等)。代码如下:

create view vw_stuinfo as
select a.stuid,--学号
    a.stuname,--学生姓名
    a.grade,--年级
    a.sex,--性别(1:男、2:女)
    a.age,--年龄
    b.classname,--班级
    b.monitorname,--班长
    b.headmastername--班主任
 from stuinfo a, class b
 where a.classno = b.classno;
select * from vw_stuinfo;

Oracle索引

Oracle索引(index)最大的作用是用来优化数据库查询的效率,提升数据库的查询性能。就好比书的目录一样,可以通过目录来直接定位所需内容存在的页数,大大提高检索效率。

Oracle数据库中如果某列出现在查询的条件中,而该列的数据是无序的,查询时只能从第一行开始一行一行的匹配。创建索引就是对某些特定列中的数据进行排序或归类,生成独立的索引表。在某列上创建索引后,如果该列出现在查询条件中,Oracle 会自动的引用该索引,先从索引表中查询出符合条件记录的 ROWID,由于 ROWID 是记录的物理地址,因此可以根据 ROWID 快速的定位到具体的记录,当表中的数据非常多时,引用索引带来的查询效率非常可观 。

何时建立索引

既然我们都知道建立索引有利于查询速率的提升,那是不是所有字段都可以加上索引。这是万万不行的,建立索引不仅仅要浪费空间来存储索引表,当数据量较少时,直接查询数据比经过查询索引表再定位到表数据的速度更快。索引可以提高查询的效率,但是在数据增删改时需要更新索引,因此索引对增删改时会有负面影响。所以要根据实际情况, 考虑好再建立索引。

那何时建立索引,下面大概介绍几点,其余的得在实际应用和开发过程中,酌情考虑:

1、Oracle 数据库会为表的主键和包含唯一约束的列自动创建索引,所以在建立唯一约束时,可以考虑该列是否必要建立。是否经常要作为查询条件。

2、如果某个表的数据量较大(十几二十万以上),某列经常作为where的查询条件,并且检索的出来的行数经常是小于总表的5%,那该列可以考虑建立索引。

3、对于两表连接的字段,应该考虑建立索引。如果经常在某表的一个字段进行Order By 则也经过进行索引。

4、不应该在小表上建立索引。上面也说过,小表之间查询的数据会比建立索引的查询速度更快,但是在某些字段,如性别:只有男、女和未知三种数据时,可以考虑位图索引,可以增加查询效率。

5、经常进行DML操作,即经常进行增删改的操作的表,创建表索引时就要权衡一下,因为建索引会导致进行DML操作时速度变慢。所以可以根据实际情况,选择某些字段建立索引,而不能盲目乱建。

索引的类别

适当的使用索引可以提高数据检索速度,那Oracle有哪些类型的索引呢?

**1、b-tree索引:**Oracle数据中最常见的索引,就是b-tree索引,create index创建的normal就是b-tree索引,没有特殊的必须应用在哪些数据上。

**2、bitmap位图索引:**位图索引经常应用于列数据只有几个枚举值的情况,比如上面说到过的性别字段,或者我们经常开发中应用的代码字段。这个时候使用bitmap位图索引,查询效率将会最快。

**3、函数索引:**比如经常对某个字段做查询的时候经常是带函数操作的,那么此时建一个函数索引就有价值了。例如:trim(列名)或者substr(列名)等等字符串操作函数,这个时候可以建立函数索引来提升这种查询效率。

**4、hash索引:**hash索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。创建hash索引必须使用hash集群,相当于定义了一个hash集群键,通过这个集群键来告诉oracle来存储表。因此,需要在创建HASH集群的时候指定这个值。存储数据时,所有相关集群键的行都存储在一个数据块当中,所以只要定位到hash键,就能快速定位查询到数据的物理位置。

**5、reverse反向索引:**这个索引不经常使用到,但是在特定的情况下,是使用该索引可以达到意想不到的效果。如:某一列的值为{10000,10001,10021,10121,11000,…},假如通过b-tree索引,大部分都密集发布在某一个叶子节点上,但是通过反向处理后的值将变成{00001,10001,12001,12101,00011,…},很明显的发现他们的值变得比较随机,可以比较平均的分部在各个叶子节点上,而不是之前全部集中在某一个叶子节点上,这样子就可大大提高检索的效率。

**6、分区索引和分区表的全局索引:**这两个索引是应用在分区表上面的,前者的分区索引是对分区表内的单个分区进行数据索引,后者是对分区表的全表进行全局索引。分区表的介绍,可以后期再做单独详解,这里就不累述了。

索引的创建

语法结构:

create[unique]|[bitmap] index index_name --UNIQUE表示唯一索引、BITMAP位图索引
on table_name(column1,column2...|[express])--express表示函数索引
[tablespace tab_name] --tablespace表示索引存储的表空间
[pctfree n1]  --索引块的空闲空间n1
[storage     --存储块的空间
 (
  initial 64K --初始64k
  next 1M
  minextents 1
  maxextents unlimited
  )];

语法解析:

1、UNIQUE:指定索引列上的值必须是唯一的。称为唯一索引,BITMAP表示位图索引。

2、index_name:指定索引名。

3、tabl_name:指定要为哪个表创建索引。

4、column_name:指定要对哪个列创建索引。我们也可以对多列创建索引,这种索引称为组合索引。也可以是函数表达式,这种就是函数索引。

修改索引:

1、重命名索引:

alter index index_old rename to index_new;--重新命名索引

2、合并索引、重新构造索引:我们索引建好后,经过很长一段时间的使用,索引表中存储的空间会产生一些碎片,导致索引的查询效率会有所下降,这个时候可以合并索引,原理是按照索引规则重新分类存储一下,或者也可以选择删除索引重新构造索引。

alter index index_name coalesce;--合并索引
alter index index_name rebuild;--重新构造

删除索引:

drop index index_name;

查看索引:

select t.INDEX_NAME,--索引名字
    t.index_type,--索引类型
    t.TABLESPACE_NAME,--表空间
    t.status,--状态
    t.UNIQUENESS--是否唯一索引
 from all_indexes T 
 where t.INDEX_NAME='index_name';

案例分析:

**案例1、**学生信息表(stuinfo)创建的时候就对学号(stuid)设置了主键(PK_STUINFO),当我们学生信息表数据量大的情况下,我们明显发现班号(classno)需要一个索引,不仅仅是用来关联班级信息表(class)、而且经常作为查询条件,因此创建脚本如下:

create index IDX_STUINFO_CLASSNO on STUINFO (CLASSNO)
 tablespace USERS
 pctfree 10
 initrans 2
 maxtrans 255
 storage
 (
  initial 64K
  next 1M
  minextents 1
  maxextents unlimited
 );

**案例2、**对于学生信息我们经常用性别作为统计条件进行对学生信息进行统计,因此我们可以在性别(sex)建立一个位图索引进行查询优化。代码如下:

create bitmap index IDX_STUINFO_SEX on STUINFO (SEX)
 tablespace USERS
 pctfree 10
 initrans 2
 maxtrans 255
 storage
 (
  initial 64K
  next 1M
  minextents 1
  maxextents unlimited
 );

查询一下三种索引的状态:

select t.INDEX_NAME,
    t.index_type,
    t.TABLESPACE_NAME,
    t.status,
    t.UNIQUENESS
 from all_indexes T
 where t.TABLE_NAME='STUINFO'
 AND T.OWNER='STUDENT'

你可能感兴趣的:(ORACLE,oracle,数据库,plsql)