2、Oracle

  • Oracle是以用户为单位的,MySQL是以数据库为单位的

  • Java中的字符串是用双引号"",

  • 数据库中的字符串是用单引号'',

  • XML中可单可双,外单内双或外双内单

  • 注意,命令不区分大小写,但是最好养成命令大写的习惯

  • 在命令后面加 ; 是个好习惯,无论是不是可以不加 ;

2.0、执行顺序

  1. from语句

  2. where语句(结合条件)

  3. start with语句

  4. connect by语句

  5. where语句

  6. group by语句

  7. having语句

  8. model语句

  9. select语句

  10. union、minus、intersect等集合

  11. order by语句

2.0.1、语句间关系

2.0.1.1、where与having

  • where和having都是做条件筛选的

  • where执行的时间比having要早

  • where后面不能出现组函数

  • having后面可以出现组函数

  • where语句要紧跟在 from后面

  • having语句要紧跟在 group by后面

2.0.1.2、group by与having

  • group by可以单独存在,后面可以不出现having语句

  • having不能单独存在,如果需要出现,那么就必须出现在group by后面

2.0.1.3、order by

  • 如果sql语句中需要排序,那么就一定要写在sql语句的最后面

  • order by后也可以出现组函数

2.0.2、SELECT查询语句

  • SELECT 字段1,字段2...

  • FROM 表

  • WHERE 条件

  • GROUP BY 分组条件字段

  • HAVING 分组筛选条件

  • ORDER BY 排序条件

2.0.2.1、SELECT语句执行顺序

  1. from子句,组装来自表的数据,有可能是多张表

  2. where子句,基于指定的条件对记录行进行筛选

  3. group by子句,将数据划分为多个分组

  4. 使用聚合函数对每个小组中的数据进行计算

  5. having子句,进行条件筛选,这里可以使用聚合函数的计算结果

  6. 计算所有的运算表达式,主要是 select部分

  7. order by子句,对结果集进行排序

2.1、数据库的历史和特点

2.1.1、数据库所经历的阶段

  • 人工管理阶段

  • 文件系统阶段

  • 数据库系统阶段

2.1.2、数据库的发展历史

  • 第一代数据库系统:层次和网状数据库管理系统

  • 第二代数据库系统:关系数据库管理系统(RDBMS)

  • 第三代数据库系统:目前此阶段仍处于发展中

2.1.3、数据库的特点

  1. 实现数据共享

  2. 减少数据的冗余度

  3. 数据的独立性

  4. 数据实现集中控制

  5. 数据的一致性和可维护性,以确保数据的安全性和可靠性

  6. 故障恢复

2.1.4、四代编程语言

  • 第一代编程语言,机器语言,是面向机器的,通过二进制代码对其计算机操作

  • 第二代编程语言,汇编语言,使用指令对应的符号,来代替二进制代码

  • 第三代编程语言,高级开发语言 ,例如C、C++ Java等,语言更加简单,操作更方便

  • 第四代编程语言,只告诉计算机需要做什么,不需要告诉计算机怎么做,更加接近自然语言

2.2、数据库的各种知识和方法(不包含建表设计)

2.2.1、小方法

$cls;  清屏  在Ubuntu中是  !clear
show user;  展示当前用户名
exit  退出登录
@本地文件路径  执行本地sql文件
​
修改当前会话的语言环境
alter session set nls_language=english;
alter session set nls_language='simplified chinese';
​
select table_name from user_tables;  查看当前用户下的所有表
desc 表名  查看表结构
​
commit;  提交结果

2.2.2、登录数据库

sqlplus  再依次输入用户名和密码
sqlplus  用户名/密码
​
用DBA的身份登录,此情况不需要密码,但是这种情况需要当操作系统的用户有权限才行
并且登录后无法操作数据库
sqlplus  "/as sysdba"
​
切换用户
conn  再依次输入用户名和密码
conn  用户名/密码

2.2.3、创建用户、授权、删除用户

create user test1 identified by test1;  创建用户test1,并设置密码为test1
​
grant connect,resource to test1;  把角色connect和resource授权给test1,也可以说是赋予权限
​
drop user test1 cascade;  删除test1用户

2.2.3.1、用户权限

2.2.3.1.1、角色
  • CONNECT:角色,基本的连接

  • RESOURCE:角色,程序开发

  • DBA:角色,数据库管理

2.2.3.1.2、直接授予的系统权限

CREATE DATABASE LINK、CREATE MATERIALIZED VIEW、

CREATE PROCEDURE、CREATE PUBLIC SYNONYM、CREATE ROLE、CREATE SEQUENCE、CREATE SYNONYM、CREATE TABLE、

CREATE TRIGGER、CREATE TYPE、CREATE VIEW

2.2.3.2、数据库对象

数据库对象是数据库的组成部分,常常用 CREATE 命令进行创建,可以使用 ALTER 命令修改,用 DROP执行删除操作

  • 用户(user)

  • 表(table)

  • 视图(view)

  • 索引(index)

  • 触发器(trigger)

  • 存储过程(procedure)

  • 同义词(synonym)

  • 序列(sequence)

2.2.4、sqlplus的buff

  • 使用 sqlplus 登录之后,可以使用 buff(缓存)来存储/执行/修改上一条运行的sql语句

  1. buff中只能存储一条sql语句,但是这条sql语句可能有很多行

  2. 每次放入新的sql语句,会把之前的覆盖掉

  3. 每次执行sql语句,都会把这个sql语句放到buff里面

  4. 若sql语句有多行,可以输入数字来进行 定位

2.2.4.1、sqlplus的buff的相关命令

  • l:查看缓存中的sql语句,会显示行号

  • a:在[定位]的那一行后面追加新的内容

  • i:在[定位]的那一行下面插入新的一行

  • c:替换[定位]的那一行中的某些字符串 ,格式为:c/老的字符串/新的字符串

  • del:删除[定位]的那一行内容

  • n:后面加内容可以重写这一行

  • $:后面跟一个终端命令,例如$cls清屏,在linux中使用!

  • /:执行缓存的sql命令

  • clear buff:清除buff中的sql语句

2.2.4.2、一些其他命令

  • save test.sql:buff中的sql语句保存在test.sql文件中

  • get test.sql:把test.sql中的内容在加载到buff中,但是没有运行

  • start test.sql:把test.sql中的内容在加载到buff中并且执行

  • @test.sql:把test.sql中的内容在加载到buff中并且执行

  • edit file_name:使用系统默认编辑器去编辑文件

  • spool 命令:可以记录操作的过程 spool file_name //将接下来的sql语句以及sql的运行结果保存到文件中

sql1

result1

sql2

result2

...

spool off //关闭spool功能

2.2.5、对表的操作方法

2.2.5.1、sql语句的分类

  • DQL (Data Query Language),数据查询语言,用于检索数据库中的数据,主要是 SELECT 语句

  • DML (Data Manipulation Language),数据操纵语言,用于改变数据库中的数据,主要是 INSERT , UPDATE , DELETE 语句

  • DDL(Data Define Langage),数据定义语言,用来建立、修改、删除数据库对象,主要是 CREATE、 ALTER 、 DROP 、 TRUNCATE 语句

  • TCL (Transaction Control Language),事务控制语言,用于维护数据的一致性,主要是 COMMIT , ROLLBACK, SAVEPOINT 语句

  • DCL(Data Control Language),数据控制功能用于执行权限授予和权限收回操作,主要是 GRANT , REVOKE 语句

  • 注意:DML语句需要事务的支持(产生事务),DDL语句会自动提交事务

2.2.5.2、sql、sqlplus、pl/sql的区别

  • sql:结构化的查询语句,操作关系型数据库的语言

  • sqlplus:oracle数据库软件自带工具,可以接收用户输入的sql语句,然后将sql执行结果显示出来

  • pl/sql:程序化的sql语句,在sql语句的基础上加入一定的逻辑操作,如 if for 等

2.2.5.3、SELECT

  • select语句是不会改变数据库中的数据的,你在语句中作的所有操作只会改变返回出来的结果

select * from s_emp;  返回s_emp表中所有记录的所有字段
​
select id,name from s_dept;  返回s_emp表中所有记录的指定字段
​
select id*10+2,name from s_dept;  得到作运算后的返回结果
​
并将字段改名,改名可以使用 as,也可以使用 空格
select id as ID,name NAME from s_emp;
​
使用 || 将多个字段名和字符串 拼接 在一起,
可以改名也可以不改名,但最好改一下,否则字段名太长了
记住,拼接字符串是用单引号 ''
select id,first_name||’再加一个‘||last_name  name from s_emp;
​
使用 nvl(可能值为null的字段名, 你想放的替换值)
可以将为null的值替换成你指定的值,当然也最好起个别名
select id,last_name,nvl(commission_pct,0) commission_pct from s_emp;
​
distinct可以用来去重,去重是这条记录一模一样才会去重
只能放在select之后,字段名之前
select distinct id1, id2 from s_emp;
​
format,可以修改指定字段的列宽,即 _ 的个数
column last_name format a15;
可简写成这样
col last_name for a15;
清除设置的格式
clear column  或  clear col

2.2.5.4、排序、分组

2.2.5.4.1、order by
  • order by语句,只对查询记录显示调整,并不改变查询结果,所以执行权最低,最后执行,所以order by一般放在最后面

  • 排序的默认值是asc:表示升序,desc:表示降序

  • 如果有多个列排序,后面的列排序的前提是前面的列排好序以后有重复(相同)的值

  • order by 列名 nulls first(last) 可以将null放在前面或后面

  • Oracle中null默认是最大值

查看员工的id,名字和薪资,按照薪资的降序排序显示,工资相同就按名字升序排
select id,last_name,salary from s_emp order by salary desc,last_name;
2.2.5.4.2、group by
  • 按照某一字段对数据进行分组

  • 优先级比 order by 高

  • group by多行就是依次进行分组,在前面分完组的基础上再分组,简而言之就是 多个字段都一样的才分为一组,有不同就分为两组

  • 注意:假如你select了三个字段a、b、c,只有c是聚合函数,那么你group by就必须是 a,b 都要写上,否则它只按 a或b分组,你的 b或a 不能放在同一个框里面 例如:select class,subject,count(*) from t_test group by class,subject order by class;

一位class是1,2,3这种数据,subject是数学分析、英语这种数据,如果你只按class分组,那么数据分析、英语怎么放在一个框里面?

即:如果select、having语句后面出现了组函数,那么select、having后面没有被组函数修饰的列,就必须出现在group by 后面

  • GROUP BY语句你要是放了一些你不想进行分组,但为了写得少点却不得不写进去的时候,一定要分开写,不能贪那一点代码

  • 因为 GROUP BY是先分组再使用聚合函数,所以多排会出错 例如:你希望得到部门的平均工资大于41部门的平均工资的部门的员工信息,你这样写就无法实现,因为你的分组并不是按部门来分的,你还结合了多余的两个字段

SELECT id,first_name,dept_id
FROM s_emp
GROUP BY dept_id,id,first_name
HAVING AVG(salary)>
    (SELECT AVG(salary)
    FROM s_emp
    WHERE dept_id=41);
  • 这样就是对的

SELECT *
FROM s_emp
WHERE dept_id IN
    (SELECT dept_id
    FROM s_emp
    GROUP BY dept_id
    HAVING AVG(salary)>
        (SELECT AVG(salary)
        FROM s_emp
        WHERE dept_id=41));
select id,dept_id,count(*),sum(salary) from s_emp
group by id,dept_id
order by dept_id;

2.2.5.5、条件查询

2.2.5.5.1、where
  • 限制查询条件,使用where子句

  • 条件可以多个,使用逻辑操作符或者小括号进行条件的逻辑整合

  • where子句的优先级别最高,所以一般放在from的后面

  • 比较操作表达式由操作符和值组成

  • 逻辑比较操作符 <、>、=、<=、>=、!=(<>、^=)

select id,last_name,salary from s_emp where salary < 1000;
2.2.5.5.2、between and
  • 表示在两个值之间,包括这两个边界值

select id,last_name,salary from s_emp where salary between 700 and 1500;
2.2.5.5.3、in()

表示要在枚举列表中的值

select id,last_name,salary from s_emp where id in (1,3,5,7,9);
2.2.5.5.4、like、not like
  • 模糊查询

  1. %:通配任意个字符

  2. _:通配一个字符,并且必须有一个字符

  3. \:转义字符,需要使用escape关键字指定 '' ,表示只转义一个字符

select id,last_name,salary from s_emp where last_name like 'C%';
​
select id,last_name,salary from s_emp where last_name like '___n_%';
​
select id,last_name,salary from s_emp where last_name like '%\_%' escape '\';
2.2.5.5.5、is null、is not null

判断值是否为null的时候使用,null值的判断不能使用等号

select id,commission_pct from s_emp where commission_pct is null;
2.2.5.5.6、and、or

逻辑操作符,and的优先级高于or

select id,last_name,dept_id,title from s_emp
where salary > 1000 and ( dept_id = 41 or dept_id = 44 );

2.2.5.6、多表查询

2.2.5.6.1、笛卡尔积

如果直接查询俩张表,那么其查询结果就会产生笛卡尔积

select count(*) from s_emp,s_dept;
2.2.5.6.2、等值连接
  • 利用一张表中某列的值,和另一张表中某列的值相等的关系,把俩张表连接起来,满足条件的数据才会组合

select se.last_name,se.dept_id,sd.id,sd.name from s_emp se,s_dept sd
where se.dept_id=sd.id;
2.2.5.6.3、不等值连接

不常用,就是用列名去与列名比较

select e.last_name, e.title, e.salray, s.gradeName 
from s_emp e, salgrade s
where e.salray betweeb s.losal and s.hisal
2.2.5.6.4、外连接
  • 外连接多用于值为null,或没有值的情况,这时候直接使用等值连接就会出错

  • outer可以省略不写

  1. 左外连接

  • left join on:就是左边的表的数据要全部,以左表为基表

  • 要把 where 变成 on

select last_name,dept_id,name
from s_emp left outer join s_dept
on s_emp.dept_id=s_dept.id;
  • 简写方式 右表加 (+)

select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+);
  1. 右外连接

  • right join on:就是右边的表的数据要全部,以右表为基表

select last_name,dept_id,name
from s_emp 
  right outer join s_dept
on s_emp.dept_id=s_dept.id;
  • 简写方式 左表加 (+)

select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;
  1. 全连接

  • full join on:左右表的数据都要全部

  • 查询所有员工以及对应的部门的名字,没有任何员工的部门也要显示出来,没有部门的员工也要显示出来

select last_name,dept_id,name
from s_emp full outer join s_dept
on s_emp.dept_id=s_dept.id;
2.2.5.6.5、自连接
  • 自连接就是一张表,自己和自己连接后进行查询,起别名就分成两个表

//  领导也是员工,所以想看所有的 员工及员工的领导的信息 需要自连接
select s1.last_name,s2.last_name manager_name
from s_emp s1,s_emp s2
where s1.manager_id = s2.id;
2.2.5.6.5、内连接
  • inner join ... on ...

2.2.5.7、子查询

  • 子查询,也称嵌套查询,即一个select语句中嵌套了另外的一个或者多个select语句

  • 子查询的思路就是,把第一个sql语句的查询结果,在第二个sql语句中使用,这时候第一条sql语句的结果,在第二条sql中就可以充当一个where条件中的一个值,或者充当一张虚拟的表

查询平均工资比 41号部门的平均工资 高 的部门中员工的信息,并且显示出当前部门的平均工资
​
select se.last_name,se.salary,se.dept_id,temp.avgSal
from s_emp se,(
  select dept_id,avg(salary) avgSal
  from s_emp
  group by dept_id) temp
where se.dept_id in(
  select dept_id
  from s_emp
  group by dept_id
  having avg(salary)>(
    select avg(salary)
    from s_emp
    where dept_id=41
  )
) and se.dept_id = temp.dept_id;

2.2.5.8、分页查询

  • 实现分页的方式有很多,并且不同数据库,实现分页查询的方式也会不同,那么在Oracle中,可以使用伪列rownum,再结合子查询来进行简单的实现

select t.id,t.last_name,t.dept_id
  from (
  select rownum rn,id,last_name,dept_id
  from s_emp
  where rownum<=10
) t
where t.rn>=6;

2.2.6、在查询语句块中使用别名

2.2.6.1、先在FROM中拿到带别名的数据表

SELECT emp.* FROM (SELECT last_name||first_name name FROM s_emp) emp WHERE name NOT LIKE '%s%';

2.2.7、函数

  • 数据库中的下标都是从1开始,如何如果你给值 -1,那就是反着来

  • 函数可以进行嵌套

  1. 单行函数

    • 字符函数

    • 日期函数

    • 数字函数

  2. 转换函数

  3. 聚合函数

2.2.7.0、常用函数

函数 说明
AVG() 返回平均值
SUM() 返回总和
COUNT() 返回结果的行数
MAX() 返回最大值
MIN() 返回最小值
FIRST() 返回第一个记录的值
LAST() 返回最后一个记录的值
UPPER() 将某个字段变成大写
LOWER() 将某个字段变成小写
SUBSTR(X, START, LENGTH) 从X的下标START开始,截取LENGTH长度
LENGTH() 返回字符串的长度

2.2.7.1、单行函数

2.2.7.1.1、哑表
  • Oracle中,有一张特殊的表:dual

  • dual被称之为哑表,它是一个单行单列的虚拟表,是Oracle内部自动创建的,这个表只有1列:DUMMY,

  • 数据类型为VERCHAR2(1),dual表中只有一个数据'X',Oracle有内部逻辑保证dual表中永远只有一条数据

  • 在实际使用中,Dual表主要用来选择系统变量或求一个表达式的值,因为要使用dual来构造完成的查询语法

select 1+1 from dual;
2.2.7.1.2、字符函数
函数 说明
ASCII(X) 返回字符X的ASCII码
CONCAT(X,Y) 连接字符串X和Y
INSTR(X,STR ,START ) 从X中查找str,可以指定从start开始,也可以指定从n开始
LENGTH(X) 返回X的长度
LOWER(X) X转换成小写
UPPER(X) X转换成大写
INITCAP(X) X首字母转换为大写,其他字母小写
LTRIM(X[,TRIM_STR]) 把X的左边截去trim_str字符串,缺省截去空格
LTRIM(X[,TRIM_STR]) 把X的左边截去trim_str字符串,缺省截去空格
RTRIM(X[,TRIM_STR]) 把X的右边截去trim_str字符串,缺省截去空格
TRIM([TRIM_STR<br>FROM]X) 把X的两边截去trim_str字符串,缺省截去空格
REPLACE(X,old,new) 在X中查找old,并替换成new
SUBSTR(X,start[,length]) 返回X的字串,从start处开始,截取length个字符,缺省length,默认到结尾
2.2.7.1.3、数字函数
函数 说明
ABS(X) X**的绝对值ABS(-3)=3**
ACOS(X) X**的反余弦ACOS(1)=0**
COS(X) 余弦**COS(1)=0.54030230586814**
SIN(X) 正弦**SIN(0)=0**
ASIN(X) X**的反正弦ASIN(0)=0**
CEIL(X) 大于或等于**X的最小值(整数) CEIL(5.4)=6**
FLOOR(X) 小于或等于**X的最大值(整数) FLOOR(5.8)=5**
LOG(X,Y) X**为底Y的对数LOG(2,4)=2**
MOD(X,Y) X**除以Y的余数MOD(8,3)=2,若mod 负数,那么一定=0**
POWER(X,Y) X**的Y次幂POWER(2,3)=8**
ROUND(X[,Y]) X**在小数点第Y位四舍五入ROUND(3.456,2)=3.46<br>以小数点为基准点0,1就是将小数点后一位后面的进行四舍五入,<br>-1就是将小数点前一位后面的进行四舍五入**
SQRT(X) X**的平方根SQRT(4)=2**
TRUNC(X[,Y]) X**在小数点第Y位截断TRUNC(3.456,2)=3.45**
2.2.7.1.4、日期函数
  • 注意:日期可以直接进行 -,但不可 +,结果得到十分精确的小数,可以进行round截取

  • sysdate ,是Oracle中用来表示当前时间的关键字,并且可以使用它来参与时间运算

  • sysdate 参与时间的加减操作的时候,单位是天

//显示时间:昨天的这个时候
select sysdate - 1 from dual;
//显示时间:1小时之后的这个日期
select sysdate + 1/24 from dual;
函数 说明
MONTHS_BETWEEN 俩个日期之间相差多少个月**(单位是月)**
ADD_MONTHS 返回一个日期数据:表示一个时间点,往后推*x月的日期<br>ADD_MONTHS(sysdate, 112)这样就可以+一年了<br>当然给负数就是-了**
NEXT_DAY 返回一个日期数据:表示一个时间点后的下一个星期几在哪一天
LAST_DAY 返回一个日期数据:表示一个日期所在月份的最后一天
ROUND 对日期进四舍五入,返回操作后的日期数据
TRUNC 对日期进行截取 和**round类似,但是只舍弃不进位**
INTERVAL 语法:INTERVAL '时间差数值'  { YEAR | MONTH | DAY | HOUR | MINUTE | SECODE} (精度数值)<br>适用于年、月、日、时、分、秒的操作<br>例如:SYSDATE + INTERVAL '11' YEAR(2)<br>单引号''中写正数就是+,写负数就是-
月日 缩写,不区分大小写
January Jan
February Feb
March Mar
April Apr
May May
June Jun
July Jul
August Aug
September Sep
October Oct
November Nov
December Dec
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

2.2.7.2、转换函数

2.2.7.2.0、日期时间、日期时间格式(大小写不区分)
  • 单引号 '' 中的格式就是会输出给你的东西,你写DDD就会在那一块返回这是这一年的第几天的数字,你在逗号间加空格,结果也会有空格

这里虽然写的是AM,但是它是一个变化的值,下午的时候就会自动显示为PM
select to_char(sysdate,'yy-mm-dd hh:mi:ss AM') from dual;
格式 说明
yyyy 四位数的年份
rrrr 四位数的年份
yy 两位数的年份
rr 两位数的年份
mm 两位数的月份(数字)
D 一周的星期几
DD 一月的第几天
DDD 一年的第几天
YEAR 英文的年份
MONTH 英文全称的月份
mon 英文简写的月份
ddsp 英文的第几天**(一个月的)**
ddspth 英文序列数的第几天**(一个月的)**
DAY 全英文的星期
DY 简写的英文星期
hh 小时
mi 分钟
ss
yy-mm-dd hh:mi:ss AM 年-月-日 时-分-秒 AM/PM

####

  • 为了处理千年虫问题,后面就有了一种新的日期格式: rr

  • 如果在存储日期数据的时候,年份采用的格式为rr,并且只提供了最后2位年份,那么年份中的前两位数字就由两部分共同确定

  1. 规则就是有 0-49 和 50-99 这两个区间,

  2. 如果 指定年份的后两位数字 与 当前年份的后两位数字 都在同一个区间,那么 指定年份的前两位数字 就等于 当前年份的前两位,

  3. 如果 指定年份的区间 与 当前年份的区间不同,比当前年份区间大,那么 指定年份的前两位数字 就等于 当前年份的前两位 -1,比当前年份的区间小,那就 +1。

2.2.7.2.1、TO_CHAR
  • 把一个数字或日期数据转换为字符

select to_char(salary,'L999,999.00') as result from s_emp;
SELECT TO_CHAR(start_date,'yyyy/mm/dd') FROM s_emp;
参数 示例 说明
9 999 指定位置处显示数字
. 9.9 指定位置返回小数点
, 99,9 指定位置返回一个逗号
$ $999 数字开头返回一个美元符号
L L999 数字开头返回一个本地的货币符号
PR 999PR 如果数字式负数则用尖括号进行表示
2.2.7.2.2、TO_NUMBER

把字符转换为数字

select to_number('1000') from dual;
2.2.7.2.3、TO_DATE

把字符转换为日期

select to_date('10-12-2022','dd-mm-yyyy') as result from dual;
2.2.7.2.4、关于时间操作或比较的方法
  • 日期之间相减,会得到天数的准确小数,可用TRUNC截取

  • 显示当前时间,查询当前时间是这年的第几天?是这个月的第几天?是这个周的第几天? SELECT TO_CHAR(sysdate,'DDD, DD, D') FROM dual;

  • 显示所有雇员的姓以及满10年服务年限的日期

  1. ADD_MONTHS(start_date, 11210)

  2. start_date+INTERVAL '10' YEAR

  • 至今的天数 TRUNC(sysdate-start_date)

  • 找出早于23年之前受雇的雇员

  1. start_date<=(sysdate+ INTERVAL '-23' YEAR)

  2. start_date<=(ADD_MONTHS(sysdate, -11223))

2.2.7.4、聚合函数

  • 聚合函数,一般会操作多组数据,并对每一组中的某个列,执行计算并返回单一的值。

  • 聚合函数经常与 SELECT 语句的 GROUP BY 子句一同使用,所以也把其它称之为分组函数

  • 聚合函数可出现的位置:select后面、having后面、order by后面

  • 如果select、having语句后面出现了组函数,那么select、having后面没有被组函数修饰的列,就必须出现在group by 后面 使用聚合函数时:

  • 如果还使用了group by分组,那么就表示先分组,然后对每一个小组使用聚合函数

  • 如果没有使用group by分组,那么就表示全部数据是一个默认小组,然后对这个全部数据使用聚合函数

聚合函数 说明
avg 平均值
count 结果数据行数
max 最大值
min 最小值
sum 总和

2.2.8、操作结果集

  • 每一条sql语句,查询出的一个结果,都可以被称为结果集

  • 如果有俩条sql语句,它们分别查询出的结果集,都包含完全一致的字段名称和类型,那么我们可以使用下面的关键字对俩个结果集进行操作

2.2.8.1、union

  • 取俩个结果集的并集,即全都要,会去重

select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
union
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

2.2.8.1、union all

  • 把俩个结果集合在一起显示出来 ,不去重

select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
union all
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

2.2.8.1、minus

  • 第一个结果集除去第二个结果集和它相同的部分

  • 即第二有的数据第一个不要

select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
minus
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

2.2.8.1、intersect

  • 求俩个结果集的交集,即一样的部分才要

select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id=s_dept.id(+)
intersect
select last_name,dept_id,name
from s_emp,s_dept
where s_emp.dept_id(+)=s_dept.id;

2.2.9、rownum(伪列)

  • Oracle中,有一个特殊的关键字rownum,被称为:伪列

  • rownum只有Oracle数据中才有

  • rownum (伪列),就像表中的列一样,但是在表中并不存在。

  • 伪列并不能像表中真实的列一样随便操作,伪列只能用于查询

  • 伪列,可以根据查询结果的条数,自动生成,并且一定是从1开始连续不断的数字

  • 伪列rownum的本质就是给查询的一行行结果标上行号

  • rownum只能 =1,或 >0,或 <一个大于1的数字

  • Oracle数据库中伪列rownum最核心的作用就是:完成分页查询

select rownum,last_name from s_emp;

2.2.9.1、将rownum当作字段进行操作的方法

弄个子查询,在子查询中使用rownum,就可以操作rownum字段了

select t.id,t.last_name,t.dept_id
from (
  select rownum rn,id,last_name,dept_id
  from s_emp
  where rownum<=10
) t
where t.rn>=6;

2.2.10、授权、取消授权

//将自己的表s_emp的查询权限给test1用户,并且该用户可以继续授权此表
grant select on s_emp to test1 with grant option;
​
//将A表所有的序列的查询权限给B
select 'grant select on ' || sequence_name || ' to b;'
from dba_sequences
where sequence_owner='A';
​
revoke delete on a.tablename from b;  //取消a给b对于表的删除权限
revoke update on a.tablename from b;  //取消a给b对于表的更新权限
revoke select any table from b;  //取消a给b对于表的查询权限
revoke create database link from b;

2.2.11、查看当前用户的所有权限

select * from user_tab_privs;

2.3、数据库的设计

级联:cascade constraint

2.3.1、数据建模

2.3.1.1、软件开发流程

每一项又可以细分为多个环节

  • 分析

  • 设计

  • 编码

  • 测试

  • 部署

  • 上线

  • 运维

2.3.1.2、数据建模流程

  1. 概念建模

  • 客户交流

  • 理解需求

  • 形成实体 在业务复杂的时候,我们通过不能很快理解这个业务流程中的每个步骤,并且可能在客户的很多业务中,会有一些相同的步骤,这些都是需要我们反复和客户进行沟通后,才有可能有一个比较全面的掌握。

所以,这一般是一个迭代的过程,需要反复多次的和客户沟通、理解和确认

  1. 逻辑建模 此阶段主要是对概念建模阶段的实体进行细化、优化、测试等。

最后形成具体的E-R图(实体关系图),这张关系图中详细记录了实体信息,同时展示了实体与实体之间的关系

  1. 物理建模 此阶段中,将在逻辑建模阶段创建的实体关系图,根据选择使用的数据库,转为相应的 SQL代码,以便在数据库中,创建相应数据库对象。

由于之后系统中的功能,主要就是围绕数据库进行实现的,所以此时还需要在数据库中,模拟测试数据并插入到表中,然后对前期需求分析中的功能,进行测试,以便能及时发现问题并处理。

最后,还可以针对系统的实际业务特点,考虑是否需要对数据库中的表进行拆分、读写分离等

2.3.1.3、E-R图

2.3.1.3.1、E-R图三要素
  • 实体 用来表示据有相同特征和性质的事物,实体由实体名和实体属性组成

  • 属性 实体所具有的某一特性就是它的属性,一个实体可以拥有多个属性

  • 关系 有一对一关系、一对多关系、多对多关系

2.3.1.3.2、实体间的连接方式
  1. 一对一关系

  • 外键可设置在任意一张表中 例如,妻子和丈夫

  1. 一对多关系

  • 外键要设置在多的那一方,因为每个多方的记录只需要填写一个字段,而若是设置在了一的那一方,那每次多一个引用或少一个引用都需要修改表结构,所以要在多的那一方设置一个字段来关联一这一方 例如,班级和学生

  1. 多对多关系

  • 假设是A表和B表,这种情况下,需要设计第三张表(桥表),桥表中设置俩个外键,分别引用A表的主键和B表的主键,当然也可以两方都设置一个字段 例如,学生和老师

2.3.1.3.3、说明
  • ,表示唯一

    • ,表示非空

  • o ,表示可以为空

  • 虚线:表示may be

  • 实现:表示must be

  • 表示关系的连线,伞状的一端表示多的一方,另一端表示一的一方

  • 连线上面还有可以加上文字说明

2.3.1.3.4、E-R图形
  • 矩形或圆角矩形,表示实体

  • 菱形,描述关系

  • 圆形,表示属性

  • 连线,表示关系

2.3.1.3.5、E-R图转成数据库中的表
  • 实体的名字转换为表的名字

  • 实体的属性转换为表中的列

  • 具有唯一特点的属性设置为表中的主键

  • 根据实体之间的关系,设置表中某列为外键列(主外键关联)

2.3.2、数据库设计

2.3.2.1、主键

主键的作用,就是用来唯一标识一行数据的

2.3.2.1.1、特点
  1. 能做主键的列必要满足非空唯一的特点

  2. 只要满足非空唯一的任何列都可以做主键

  3. 可以让表中一个有意义的列做主键 例如,学号,它既表示学生的学号,又作为表中的主键,因为这个列满足非空唯一的条件

  4. 也可以找一个没有意义的列做主键 其作用就是标识一行数据,大部分情况下都是用没有意义的列去做主键,例如ID列

  5. 可以让多个列联合在一起做表中的主键 这个主键就是一个联合主键,要求这几个列的值联合在一起是非空唯一的

2.3.2.2、外键

外键的作用,就是用来标识这个类中的数据,是引用另一种表的一个字段值

2.3.2.2.1、特点
  1. 表中的某一个列声明为外键列,一般这个外键列都会引用另外一张表的主键列的值。 其实只要是具体唯一约束的列,就可以被另一种表的外键列所引用。

  2. 一张表的主键列中出现过的值,都可以在另一张表的外键列中使用。

  3. 外键列值也可以为空的,提前是这个外键列没有做主键或联合主键。

  4. 如果把B表中的联合主键,引用到A表中做外键,那么这个外键就是一个联合外键 B表的主键被A表当外键

  • B中是外键的记录不可被删除,不是外键的记录可被删除

  • 在A表被删除之前,B表一定不能被删除,除非加上级联 cascade constraints

2.3.2.3、范式

  • 设计关系数据库时,要遵从规范要求,才能设计出更加合理的表结构

  • 这些不同的规范要求被称为不同的范式,各种范式依次递进,越高的范式数据库冗余越小

2.3.2.3.1、第一范式(1NF)

一个表中,每个列里面的值是不能再分割的

2.3.2.3.2、第二范式(2NF)

第二范式是在满足第一范式的基础上,表中的非主键列都必须依赖于主键列

2.3.2.3.3、第三范式(3NF)

第三范式是在满足第二范式的基础上,表中的非主键列都必须直接依赖于主键列,而不能间接的依赖,也就是不能出现依赖传递

2.3.2.3.4、巴斯-科德范式(BCNF)
2.3.2.3.5、第四范式(4NF)
2.3.2.3.5、第五范式(5NF,完美范式)

2.3.2.4、建表(CREATE)

2.3.2.4.1、两种建表的方式

中括号[]中的内容可选

-- 格式1
create table 表名(
字段名 数据类型 [列约束类型],
字段名 数据类型 [列约束类型],
字段名 数据类型 [列约束类型],
字段名 数据类型 [列约束类型],
字段名 数据类型 [列约束类型]
);
​
​
​
-- 格式2
create table 表名(
字段名 数据类型 [列约束类型],
字段名 数据类型 [列约束类型],
字段名 数据类型 [列约束类型],
字段名 数据类型 [列约束类型],
[表级约束],
[表级约束]
);
2.3.2.4.2、建表元素

关键字、表名、列名、数据类型、约束、固定格式

2.3.2.4.3、表和列的命名规则
  1. 必须是字母开头

  2. 必须是1-30个字符之间的长度

  3. 表名中只能出现字母、数字、_、#

  4. 不能和数据库中己有对象的名字重复

  5. 不能是数据库中的关键字

2.3.2.4.4、数据类型
  1. char、varchar、varchar2:都是存储字符串

  • char 存储数据的长度是固定的,varchar2 存储数据的长度是可变的。

  • char 效率比varchar2效率高

  • varchar是数据库标准类型,varchar2类型是oracle数据库中特有的

  • varchar2不能存空字符串,可以存null,varchar可以存空字符串

  • Oracle建议使用VARCHAR2

  1. number(p,s)、number()

  • p 表示最大位数(整数位+小数位), s表示保留的小数位(四舍五入),也可以为负数。

  • 其实这时候整数位最大只能有3位,因为要留俩位给小数位

  • 可以直接使用number,不加参数,描述没有默认没限制

  1. date 日期类型

  2. blob 存二进制对象,例如视频,音频,图片等

  3. clob 存储大文本,例如很多很多文字

2.3.2.4.5、列级约束、表级约束
  • 约束分为列级约束、表级约束

  • 如果要声明的约束为联合主键、联合外键、联合唯一的时候,就一定要用表级约束

  • 表级约束和列级约束对比:

  1. 表级约束和列级约束所写的位置不一样

  2. not null约束不能用表级约束来声明

  3. 表级约束和列级约束声明语法稍有所不同

  4. 如果要声明的约束为联合主键、联合外键、联合唯一的时候,就一定要用表级约束 not null不可以起表级约束

5种约束:

  1. 主键约束:PRIMARY KEY

  2. 外键约束:FOREIGN KEY

  3. 唯一约束:UNIQUE unique

  4. 非空约束:NOT NULL

  5. check约束:CHECK

  • 联合

unique(class,name)  //联合唯一约束
​
primary key(id,name)  //联合唯一主键
​
//  联合外键
customer_id number,
customer_name varchar(50),
foreign key(customer_id,customer_name) references t_customer(id,name)
  • 列级约束

create table student(
  id number constraint stu_id_pk primary key,
  name varchar2(200) not null,
  email varchar2(100) unique,
  gender char(1) check(gender in('f','m')),
  customer_id number references t_customer(id)
);
  • 表级约束

create table student(
  id number,
  name varchar2(20) not null,
  age number default 20,
  email varchar2(100),
  gender char,
  
  constraint stu_id_pk primary key(id),
  unique(email),
  check(gender in('f','m')),
  foreign key(customer_id) references t_customer(id)
);
2.3.2.4.6、给约束起名(constraint)(有需要才起名)
  • constraint是约束的意思

  • 建表的时候可以给约束起一个名字,这个名字起的规律一般会是: 表名列名约束类型

  • 如果没有给约束起名字,那么系统也会给这个约束起一个默认的名字

  • 将来我们可以根据之前给约束起好的名字,而找到这个约束,然后进行修改获取其他操作

  • 列级约束起名

create table student(
  id number constraint student_id_pk primary key,
  name varchar2(100) constraint student_name_nn not null,
  email varchar2(100) constraint student_email_un unique,
  gender char(1) constraint student_gender_ck check(gender in('f','m')),
  age number,
  birthday date
);
  • 表级约束起名

create table t_customer(
  id number,
  name varchar2(20) not null,
  age number,
  email varchar2(100),
  gender char,
​
  constraint cus_id_pk primary key(id),
  constraint cus_email_un unique(email),
  constraint cus_gender_ck check(gender in('f','m'))
);
2.3.2.4.7、ON DELETE

在声明外键约束的时候使用

  1. on delete no action:默认就是这个,删除时不做动作,不能删也就不能删

  2. on delete cascade:级联删除,把使用这个作外键的记录也全删除了

constraint order_cid_fk foreign key(customer_id) references t_customer(id)
on delete cascade
  1. on delete set null:将这个作外键的记录的外键值变成null,若外键有not null约束则会报错

constraint order_cid_fk foreign key(customer_id) references t_customer(id)
on delete set null
2.3.2.4.8、复制建表
  • 将表结构和数据全部复制

create table test1
as
select * from s_dept;
  • 将表结构复制,不复制数据

create table test2
as
select * from s_dept
where 1=2;
  • 将表结构复制,复制指定列的数据

create table test3
as
select id,last_name,salary from s_emp;
2.3.2.4.9、删除表(DROP)
DROP TABLE 表名 [cascade constraints];
2.3.2.4.10、修改表(ALTER)
  • 在表中添加新列

  • 删除表中的列

  • 给表中添加约束

  • 删除表中的约束

  • 修改表名

  • 修改列的数据类型

  • 设置约束失效

alter table t_user add birthday date;  //在表中添加新字段
​
alter table t_user drop column birthday;  //删除表中的指定字段
​
//在表中给指定字段添加表级约束
alter table t_user add unique(name);  //不起别名的情况
alter table t_user add constraint user_name_un unique(name);
​
alter table t_user drop constraint user_name_un;  //删除表中的约束
​
rename t_user to mytest;  //修改表的名字
alter table t_user rename to tt_user;
​
//修改表的字段的名字
alter table t_user rename column gender TO sex;
​
alter table t_user modify (name varchar2(500));  //修改指定字段的数据类型
​
alter table t_user disable constraint user_id_pk cascade;  //让约束失效
alter table t_user enable constraint user_id_pk;  //让失效的约束再次生效
​
truncate table t_user;  //截断表中的数据,相当于DELETE FROM t_user;commit:
2.3.2.4.11、注释(comment)
comment on table t_user is '很好';  //给表添加注释
//查看表中的注释,一定是user_tab_comments,这个user不是表名
select * from user_tab_comments where table_name=upper('t_user');
​
comment on column t_user.name is 'good';  //给列添加注释
//查看列中的注释,一定是user_col_comments
select * from user_col_comments
where comments is not null and table_name=upper('t_user');

2.3.2.5、DML语句

DML (Data Manipulation Language),数据操纵语言

DML用于改变数据库中的数据,主要包括:INSERT、UPDATE、DELETE

2.3.2.5.1、INSERT语句
//指定字段的方式可以不写上一些可以为空的字段
INSERT INTO 表名(指定列字段) VALUES(对应指定列字段的值);
​
//不指定字段的方式就要把所有的值都写上
INSERT INTO 表名 VALUES(所有列字段的值);
​
//把查询结果插入到表中
insert into t_user(id,name,birthday)
select id,last_name,start_date
from s_emp;
2.3.2.5.2、UPDATE语句
UPDATE 表名 SET 列名1=值1,列名2=值2... WHERE 条件;  //若不加条件,则会修改所有
2.3.2.5.3、DELETE语句
DELETE FROM 表名 WHERE 条件;  //若不加条件,则会删除所有

2.3.2.6、数据库事务

事务(Transaction),是由一系列对数据库表中数据,进行访问与更新的操作,所组成的一个执行逻辑单元

假如你做了DML操作,但没有commit或ddl提交,那么所有的操作都只是在当前缓存中,还没有更新到数据库中,打开两个cmd去使用数据库,就能发现

  • 只有DML语句才会产生事务,其他语句不会产生事务

  • DML语句执行的时候,如果当前有事务,那么就使用这个事务。如果当前没有事务,则产生一个新事务

  • commit、rollback、DDL语句都可以把当前事务给结束掉

  • commit和DDL语句结束事务的方式是把这个事务给提交了,然后DML操作永久生效

  • rollback结束事务的方式是把这个事务给回滚了,默认回滚到事务开始的状态,但并没有提交事务

2.3.2.6.1、数据库特性(事务特征)
  • 原子性(Atomicity):一个事务中所有的DML操作,要么同时成功,要么同时失败

  • 一致性(Consistency):事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态

  • 隔离性(Isolation):事务操作应该相互独立

  • 持久性(Durability):事务一旦被提交,对数据库的改变就是永久的

2.3.2.6.2、ROLLBACK设定回滚点(SAVEPOINT)

因为不会提交事务,所以回滚到B后可以继续回滚到A

DML语句1
savepoint A
DML语句2
savepoint B
DML语句3
rollback to A或B

2.3.2.6.3、DDL、DML、DCL、DQL语句

  1. DDL:数据定义语言 CREATE、ALTER、DROP

  2. DML:数据操作语言 INSERT、DELETE、UPDATE

  3. DCL:数据库控制语言 GRANT、DENY、REVOKE

  4. DQL:数据库查询语句 SELECT

2.3.2.7、隔离

在数据库中,使用事务隔离级别,来解决事务在并发访问中,所产生的一些问题

  1. 脏读

  • 主要针对update操作。

  • 一个事务A读到另一个事务B中修改过,但是还没有提交的数据

  • 事务A访问了数据,并做了修改,但这个修改还没有提交到数据库中,然后事务B读取了此数据,那么这个数据就是脏的,因为这不是数据库中的数据

  1. 不可重复读

  • 主要针对update操作。

  • 一个事务A在第一次读数据和第二次读数据之间,有另一个事务B把这个数据更改并提交了,所以就出现了事务A里面读一个数据俩次,但是读到的结果是不同的

  1. 幻读

  • 主要针对的是insert/delete操作。

  • 事务A第一次用where条件筛选出了10条数据,事务A第二次用通样的where条件筛选出的却是11条数据。

  • 因为事务B在事务A的第一次和第二次查询之间进行了插入操作,并且插入的这个数据满足事务A的where筛选条件

2.3.2.7.1、事务隔离级别
  • 级别越高解决的问题越多但是效率越低

  • 注意,并不是所有数据库都支持这四种事务隔离级别 例如,oracle就只支持第二种和第四种这俩种。而mysql四种全都支持

  • 注意,具体的支持情况,不仅和数据库有关,也和数据库的版本有关

  1. read-uncommitted 读未提交

  2. read-committed 读已提交,解决了脏读

  3. read-repeatable 可重复读,解决了脏读和不可重复读

  4. serializable 三个问题都解决了

2.3.2.7.2、设置事务隔离级别
Set Transaction Isolation Level Read Uncommitted
Set Transaction Isolation Level Read Committed  //Oracle的默认事务隔离级别
Set Transaction Isolation Level Read Repeatable
Set Transaction Isolation Level Serializable
2.3.2.7.3、MySQL的事务隔离
//查看当前事物级别:
SELECT @@tx_isolation;
​
//设置read uncommitted级别:
set session transaction isolation level read uncommitted;
​
//设置read committed级别:
set session transaction isolation level read committed;
​
//设置repeatable read级别:(默认)
set session transaction isolation level repeatable read;
​
//设置serializable级别:
set session transaction isolation level serializable;
​
// 查看是否自动提交
show variables like 'autocommit';
​
-- 关闭自动提交
set autocommit = OFF

2.3.2.8、序列(Sequence)

序列(Sequence),它也是一种数据库对象

它作用主要用来帮助表去创建自动增长的主键。

序列是oracle数据库所特有的对象,其他数据库中是没有的

2.3.2.8.1、创建序列

序列就相当于会自动增长的数值,可以用来给ID赋值,给主键自动增长,

使用 序列名.nextval 来自动增长

create sequence 序列名
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE n | NOMAXVALUE}]
[{MINVALUE n | NOMINVALUE}]
[{CYCLE | NOCYCLE}]
[{CACHE n | NOCACHE}]
​
​
​
create sequence test_seq
increment by 5
start with 10
maxvalue 100
minvalue 10
cycle
nocache;
  • INCREMENT BY:用于定义序列的步长,如果省略,则默认为1

  • START WITH:定义序列的初始值(即产生的第一个值),默认为1

  • MAXVALUE:定义序列能产生的最大值。NOMAXVALUE是默认值,代表没有最大值定义

  • MINVALUE:定义序列能产生的最小值。NOMINVALUE是默认值,代表没有最小值定义

  • CYCLE 和 NOCYCLE:表示当序列的值达到限制值后是否循环

  • CACHE:定义存放序列值的缓冲区的大小,默认为20。 NOCACHE 表示不对序列进行内存缓冲

2.3.2.8.2、查询序列值
select 序列名.currval from dual;  //查看序列当前值
select 序列名.nextval from dual;  //查看序列下一个值
​
select sequence_name from user_sequences;  //查询当前用户的序列
2.3.2.8.3、删除序列
DROP sequence 序列名;

2.3.2.9、视图(View)

视图其实就是提取一张表或者多张表的数据生成一个映射

操作视图从而达到操作原表的效果,方便数据管理和安全操作

视图的主要作用是隐藏表中的重要数据、代替比较长的sql语句

  • 通过简单视图可以修改原来表中的数据,通过复杂视图是不能修改原来的数据的

2.3.2.9.1、简单视图

视图所代表的sql中,如果没有group by语句,没有组函数,查询的只有一张表,那么这样的视图就是简单视图

2.3.2.9.2、复杂视图

视图所代表的sql,中如果有group by语句,或者有组函数,或者查询的是多张表,那么这样的视图就是复杂视图

2.3.2.9.3、创建简单视图
create or replace view 视图名字 as sql语句
[with read only | with check option];
​
​
​
create or replace view v_test as
select id,last_name,salary from t_user where id < 10
with read only;
​
create or replace view v_test as
select id,name,salary from t_user where id=2
with check option;
  • with read only语句,表示只能通过该视图进行查询数据,,不能修改

  • with check option语句,表示通过视图进行的修改,那么也必须可以通过这个视图能够显示出来,否则就操作失败

2.3.2.9.4、创建复杂视图

复杂视图只能查看,不能修改

create or replace view v_test as
select avg(salary) avgSal from t_user;
2.3.2.9.5、删除视图
DROP view 视图名;

2.3.2.10、索引(index)

  • 类似书的目录结构

  • Oracle 的索引是一种对象,是与表关联的可选对象,能提高SQL查询语句的速度

  • 索引直接指向包含所查询值的行的位置,减少磁盘I/O

  • 索引和表是相互独立的物理结构

  • Oracle 自动使用并维护索引,插入、删除、更新表后,自动更新索引

  • 创建了索引并不一定就会使用,因为oracle在自动统计表的信息后,会决定是否使用索引

  • 表中数据很少时,使用全表扫描速度已经很快了,那么就没有必要使用索引了

  • 在某一个列上加入上了索引,那么也只有在数据量很大的时候,才能有所体现出这个查询的效率

  • 索引一旦建立成功,那么之后这个索引就由数据库来管理,我们自己是控制不了的

例如:一个表中有name字段,假设要查找name='tom'的数据,但是数据可能会有多条

  1. 如果没有索引,查找这个记录时,需要搜索表中所有的记录,因为不能保证只有一个tom,那么就必须将表中数据全部搜索一遍

  2. 如果在name上建立索引,oracle会对全表进行一次搜索,将每条记录的name值在什么位置按照一定的规则进行排列,然后构建索引条目,并存储起来,在查询name为tom时,可以直接查找该数据所在的对应地方

2.3.2.10.1、创建索引
  • 自动创建索引、用户创建索引 当在表中指定了primary Key或者unique约束时,会自动创建唯一值索引

用户可以创建非唯一值索引以提高在访问数据时的效率

create index 索引名 on 表名(列名);  //创建索引
​
select index_name from user_indexes;  //查看当前用户创建的索引
2.3.2.10.2、给某字段创建索引的原则
  • 列经常作为where子句的限定条件或者作为连接条件

  • 列包含的数据量很大,并且很多非空的值

  • 在经常需要order by,group by,distinct 列上创建索引,可以利用索引加快排序查询时间

  • 索引不是越多越好,不是索引越多越能加速查找

  • 要建立索引的表不经常进行修改操作

2.3.2.10.3、删除索引
DROP index 索引名;
2.3.2.10.4、索引种类
  1. 唯一值索引:unique index 创建索引时候 列的约束时唯一约束或者时主键约束

  2. 非唯一值索引:nounique index 创建索引时候 列的约束时不是唯一约束或者不是主键约束

  3. 单行索引:single index

  4. 多行索引:concatenated index

2.3.2.10.5、索引结构
  1. B-tree索引 默认的索引就是这种结构

  • 适合大量的增、删、改

  • 不能用包含OR操作符的查询

  • 适合唯一值较多的列

  • 典型的树状结构

create index emp_index on s_emp(last_name);
drop index emp_index;
  1. 位图索引 数据基数比较少的时候,较适合建位图索引

  • 非常适合OR操作符的查询

  • 做UPDATE代价非常高,因为oracle要根据表的每次修改来更新索引

create bitmap index bitmap_index on s_emp(last_name);
drop index bitmap_index;
//查询当前数据库版本是否支持bitmap索引的功能
select * from v$option Where PARAMETER='Bit-mapped indexes'
  1. 反序索引 反向索引是B-tree索引的一个分支,主要是在创建索引时,针对索引列的索引键值进行字节反转。

它可以将索引键值分散到不用的节点中

create index emp_index_reverse on s_emp(last_name) reverse;
drop index emp_index_reverse;
  1. 函数索引 经常对某个字段做查询的时候,并且是带函数操作的,那么此时函数索引就可以发挥作用,提高检索速度

create index func_index on s_emp(upper(last_name));
drop index func_index;

3

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐