oracle与sql语句

oracle与sql语句

    • 数据库基础
    • Oracle数据库安装及访问
    • Oracle相关操作
      • 创建表空间与用户
      • 创建表
        • Oracle数据类型
        • 创建表
      • 修改表
      • DML语句
        • INSERT语句
        • UPDATE语句
        • DELETE语句
      • 数据类型
        • 字符串与函数
        • 数据类型与函数
        • 日期类型与函数
      • 空值和空值函数
      • 基本查询语句
      • 去重与排序
      • 聚合函数
      • 分组
      • 关联查询
      • 内连接与外连接
      • 自连接
      • 子查询
      • 分页查询
      • DECODE函数
      • 排序函数
      • 集合操作
      • 高级分组函数
      • 视图
      • 索引
      • 约束

数据库基础

一、DB和DBMS

  • 数据库(Database,简称DB)是按照数据结构来组织、存储和管理数据的仓库。
  • 数据库管理系统(Database Management System,简称DBMS):管理数据库的软件。

二、关系数据库简介

  • 关系:描述两个元素间的关联或对应关系
  • 使用关系模型把数据组织到二维数据表(Table)中
  • 产品化:Oracle、DB2、Sybase、SQL Server、Mysql

三、表的概念

  • 一个关系数据库由多个数据表(Table)组成,数据表是关系数据库的基本存储结构
  • 表是二维的,由行和列组成
  • 表的行(Row)是横排数据,也被称作记录(Record)·表的列(Column)是纵列数据,也被称作字段(Field)
  • 表和表之间存在关联关系

四、Oracle数据库概述

  • Oracle是著名的Oracle(甲骨文)公司的数据库产品
  • Oracle是世界上第一个商品化的关系型数据库管理系统
  • Oracle采用标准SQL(结构化查询语言),支持多种数据类型,提供面向对象的数据支持,具有第四代语言开发工具,支持UNIX、WINDOWS、OS/2等多种平台
  • Oracle公司的产品丰富,包括Oracle服务器、Oracle开发工具和Oracle应用软件。其中最著名的就是Oracle数据库.

五、结构化查询语言

  • SQL(Structured Query Language):结构化查询语言.
  • SQL是在关系数据库上执行数据操作、检索及维护所使用的标准语言,可以用来查询数据,操纵数据,定义数据,控制数据
  • 所有数据库都使用相同或者相似的语言
  • SQL可分为:
    ①数据定义语言(DDL) : Data Definition Language
    ②数据操纵语言(DML) : Data Manipulation Language
    ③事务控制语言(TCL) : Transaction Control Language
    ④数据查询语言(DQL) : Data Query Language
    ⑤数据控制语言(DCL) : Data Control Language

1.数据定义语言(DDL)Data Definition Language

  • 用于建立、修改、删除数据库对象
  • 包括:
    CREATE:创建表或其他对象的结构
    ALTER:修改表或其他对象的结构
    DROP:删除表或其他对象的结构
    TRUNCATE:删除表数据,保留表结构

2.数据操作语言(DML)Data Manipulation Language

  • 用于改变数据表中的数据
  • 和事务相关,执行完后需要经过事务控制语句提交后才真正的将改变应用到数据库中
  • 包括:
    INSERT:将数据插入到数据表中
    UPDATE:更新数据表中已存在的数据
    DELETE:删除数据表中的数据

3.事务控制语言(TCL)Transaction Control Language

  • 用来维护数据一致性的语句
  • 包括
    COMMIT:提交,确认已经进行的数据改变
    ROLLBACK:回滚,取消已经进行的数据改变
    SAVEPOINT:保存点,使当前的事务可以回退到指定的保存点,便于取消部分改变

4.数据查询语言(DQL) Data Query Language

  • 用来查询所需要的数据
  • SELECT语句

5.数据控制语(DCL)Data Control Language

  • 用于执行权限的授予和收回操作
  • 包括:
    GRANT:授予,用于给用户或角色授予权限
    REVOKE:用于收回用户或角色已有的权限
    CREATE USER:创建用户

Oracle数据库安装及访问

Oracle官网下载

一、远程登录数据库服务器

  • 命令行工具: Oracle自带的SQL*PLUS
  • 图形界面工具:SQL Developer
  • 默认端口号:1521

Oracle相关操作

创建表空间与用户

!--1.新建—个用户
CREATE USER C##username IDENTIEIED BY 12345;
--2.创建一个表空间
CREATE TABLBSPACE mydatabase DATAZILE 'e:\mywork\oracle\mydatabase.dbf' SIZE 2048M;
--3.将表空间分配给创建的用户,要重新启动一下数据厍
ALTER USER C##username DEFAULT TABLESPACE mydatabase;
--4.为创建的用户分配对应的权限
GRANT
    connect,resource, create indextype,create job, create sequence, create session,create table,create view, create procedure ,unlimited tablespace,insert any table
TO
    C##username;
--5.测试
SELECT sysdate FROM dual;

oracle与sql语句_第1张图片

创建表

Oracle数据类型

一、NUMBER

  • NUMBER表示数字类型
  • 经常被定义成NUMBER (P,S)形式,其中:
    P表示数字的总位数
    S表示小数点后面的位数

二、CHAR

  • 表示固定长度的字符类型
  • 经常被定义成CHAR (N)形式,N表示占用的字节数
  • 最大长度是2000字节

三、VARCHAR2

  • 表示变长的字符类型
  • 定义格式是VARCHAR2 (N),N表示最多可占用的字节数
  • 最大长度是4000字节

四、DATE

  • 用于定义日期时间的数据
  • 长度是7个字节
  • 默认格式是: DD-MON-RR,例如:11-APR-71
创建表

一、CREATE语句

CREATE TABLE [schema.]table_name(
column_name datatype[DEFAULT expr][.]
);

二、DESC语句(查看表结构)

DESC table_name;

三、DEFAULT语句

  • 可以通过DEFAULT子句给列指定默认值

四、NOT NULL

  • 非空(Not Null)是一种约束条件,用于确保字段值不为空
  • 默认情况下,任何列都允许有空值
  • 当某个字段被设置了非空约束条件,这个字段中必须存在有效值
  • 当执行插入数据的操作时,必须提供这个列的数据
  • 当执行更新操作时,不能给这个列的值设置为NULL

修改表

一、修改表名

  • 在建表后如果希望修改表名,可以使用RENAME语句实现、
  • 语法如下,将改变表名old_name为new_name:
RENAME old_name To new_name;

二、增加列

  • 给表增加列可以使用ALTER TABLE的ADD子句实现。语法:
  • 列只能增加在最后,不能插入到现有的列中
ALTER TABLE table_name ADD
(column datatype [DEFAULT expr][, columndatatype..])

三、删除列

  • 使用ALTER TABLE的DROP子句删除不需要的列。
  • 语法如下
ALTER TABLE table _name DROP](column);
  • 删除字段需要从每行中删掉该字段占据的长度和数据,并释放在数据块中占据的空间,如果表记录比较大,删除字段可能需要比较长的时间。

四、修改列

  • 建表之后,可以改变表中列的数据类型、长度和默认值·修改仅对以后插入的数据有效
  • 如果把长度由大改小,有可能不成功
  • 语法:
ALTER TABLE table_name MODIFY
(column datatype [DEFAULT expr][, column datatype...])

DML语句

INSERT语句
  • 给数据表增加记录
  • 语法如下:
INSERT INTO table _name[(column[, column...])]VALUES(value[, value..]);
  • 执行DML操作后,需要再执commit语句,才算真正确认了此操作
  • 如果插入的列有日期字段,需要考虑日期的格式默认的日期格式‘DD-MON-RR’,可以自定义日期格式,用TO_DATE函数转换为日期类型的数据
UPDATE语句
  • 更新表中的记录
  • 语法如下:
UPDATE table_name
SET column = value [, column = value]...[WHERE condition];
  • 如果没有WHERE子句,则全表的数据都会被更新,务必小心
DELETE语句
  • 删除表中的记录
  • 语法如下:
DELETE [FROM] table_name [WHERE condition];
  • 如果没有WHERE子句,则全表的数据都会被删除!
  • 在DDL语句中的TRUNCATE语句,同样有删除表数据的作用。
  • 和DELETE语句的区别:
  • DELETE可以有条件删除,TRUNCATE将表数据全部删除
  • DELETE是DML语句,可以回退,TRUNCATE是DDL语句,立即生效,无法回退
  • 如果是删除全部表记录,且数据量较大,DELETE语句效率TRUNCATE语句低。

数据类型

字符串与函数

一、CHAR和VARCHAR2类型
表示字符串数据类型,用来在表中存放字符串信息,比如姓名、职业、地址等
CHAR存放定长字符,即存不满补空格;VARCHAR2存放变长字符,存多少占用多少。

  • CHAR(100): 10个字母,补齐90个空格,实际占100(浪费空间,节省时间)
  • VARCHAR2(100):10个字母,实际占用10.(浪费时间,节省空间)
  • 按照字符的自然顺序排序

二、CHAR和VARCHAR2的存储编码
默认单位是字节,可指定为字符

  • CHAR(10),等价于CHAR(10 BYTE)
  • 指定单位为字符:CHAR(10 CHAR),20个字节
  • VARCHAR2(10),等价于VARCHAR2 (10 BYTE)
  • 指定单位为字符:VARCHAR2(10 CHAR),20个字节

每个英文字符占用一个字节,每个中文字符按编码不同,
占用2-4个字节

  • ZHS16GBK: 2个字节
  • UTF-8: 2-4个字节

三、CHAR和VARCHAR2的最大长度

  • CHAR最大取值为2000字节
    最多保存2000个英文字符,1000个汉字(GBK)

  • VARCHAR2最大取值为4000字节
    最多保存4000个英文字符,2000个汉字(GBK)

  • CHAR可以不指定长度,默认为1,VARCHAR2必须指定长度

四、LONG和CLOB类型

  • LONG: VARCHAR2加长版,存储变长字符串,最多达2GB的字符串数据
  • LONG有诸多限制:每个表只能有一个LONG类型列;不能作为主键;不能建立索引;不能出现在查询条件中…
  • CLOB:存储定长或变长字符串,最多达4GB的字符串数据
  • ORACLE建议开发中使用CLOB替代LONG类型

五、函数CONCAT和“II"

  • CONCAT(char1, char2)
    返回两个字符串连接后的结果,两个参数char1、char2是要连接的两个字符串。
  • 等价操作:连接操作符”||”
  • 如果char1和char2任何一个为NULL,相当于连接了一个空格

六、函数LENGTH

  • LENGTH(char)
    用于返回字符串的长度
  • 如果字符类型是VARCHAR2,返回字符的实际长度,如果字符类型是CHAR,长度还要包括后补的空格

七、函数UPPER、LOWER和INITCAP

  • 大小写转换函数,用来转换字符的大小写
  • UPPER(char)用于将字符转换为大写形式
  • LOWER(char)用于将字符转换为小写形式
  • INITCAP(char)用于将字符串中每个单词的首字符大写其它字符小写,单词之间用空格分隔
  • 如果输入的参数是NULL值,仍然返回NULL值

八、函数TRIM、LTRIM、RTRIM

  • 作用:截去子串
  • 语法形式:
  • TRIM(c2 FROM c1) 从c1的前后截去c2
  • LTRIM(c1[, c2]) 从c1的左边(Left)截去c2
  • RTRIM(c1[, c2])从c1的右边(Right)截去c2
  • 如果没有c2,就去除空格
  • TRIM经常用来去掉字符串前后的空格

九、函数LPAD、RPAD

  • 补位函数,用于在字符串char1的左端或右端用char2补足到n位,char2可重复多次
  • LPAD(char1, n, char2)左补位函数
  • RPAD(char1, n, char2)右补位函数

十、SUBSTR

  • SUBSTR(char, m[, n]),用于获取字符串的子串,返回char中从m位开始取n个字符
  • 如果m = 0,则从首字符开始,如果m取负数,则从尾部开始
  • 如果没有设置n,或者n的长度超过了char的长度,则取到字符串末尾为止
SELECT
SUBSTR('Doctor Who travels in TARDIS',8, 25)
FROM DUAL;
  • 字符串的首位计数从1开始

十一、INSTR

  • INSTR(char1, char2[ n [ m]]);返回子串char2在源字符串char1中的位
  • 参数:
  • 从n的位置开始搜索,没有指定n,从第1个字符开始搜索
  • m用于指定子串的第m次出现次数,如果不指定取值1
  • 如果在char1中没有找到子串char2,返回0
数据类型与函数

一、NUMBER §表示整数

  • 完整语法:NUMBER(precision , scale)
  • 如果没有设置scale,则默认取值0,即NUMBER§表示整数
  • P表示数字的总位数,取值为1-38

二、NUMBER (P,S)表示浮点数

  • NUMBER(precision , scale)
  • precision: NUMBER可以存储的最大数字长度(不包括左右两边的0)
  • scale:在小数点右边的最大数字长度(包括左侧0)
  • 指定了s但是没有指定p,则p默认为38,如:列名number (*,s)

三、NUMBER的变种数据类型
内部实现是NUMBER,可以将其理解为NUMBER的别名,目的是多种数据库及编程语言兼容

  • NUMERIC(p.s):完全映射至NUMBER(p,s)
  • DECIMAL(p,s)或DEC(p,s):完全映射至NUMBER(p,s)
  • INTEGER或INT:完全映至NUMBER(38)类型
  • SMALLINT:完全映射至NUMBER(38)类型
  • FLOAT(b):映射至NUMBER类型
  • DOUBLE PRECISION:映射至NUMBER类型
  • REAL:映射至NUMBER类型

四、ROUND

  • ROUND(n[, m]):用于四舍五入
  • 参数中的n可以是任何数字,指要被处理的数字
  • m必须是整数
  • m取正数则四舍五入到小数点后第m位
  • m取0值则四舍五入到整数位
  • m取负数,则四舍五入到小数点前m位
  • m缺省,默认值是0

五、TRUNC

  • TRUNC(n[, m]):用于截取
  • n和m的定义和ROUND(n[, m])相同,不同的是功能上按照截取的方式处理数字n

六、MOD
MOD(m, n):返回m除以n后的余数

  • n为0则直接返回m

七、CEIL和FLOOR

  • CEIL(n)、FLOOR(n)这两个函数顾名思义,一个是天花板,就是取大于或等于n的最小整数值,一个是地板,就是取小于或等于n的最大整数值
  • 比如数字n = 4.5,那么它的CEIL是5,它的FLOOR是4
日期类型与函数

一、DATE

  • ORACLE中最常用的日期类型,用来保存日期和时间
  • DATE表示的日期范围可以是公元前4712年1月1日至公元9999年12月31日
  • DATE类型在数据库中的存储固定为7个字节,格式为:
  • 第1字节:世纪+100
  • 第2字节:年
  • 第3字节:月
  • 第4字节:天
  • 第5字节:小时+1
  • 第6字节:分+1
  • 第7字节:秒+1

二、TIMESTAMP

  • ORACLE常用的日期类型
  • 与DATE的区别是不仅可以保存日期和时间,还能保存小数秒,最高精度可以到ns(纳秒)
  • 数据库内部用7或者11个字节存储,精度为0,用7字节存储,与DATE功能相同,精度大于0则用11字节存储
  • 格式为:
  • 第1字节-第7字节:和DATE相同
  • 第8-11字节:纳秒,采用4个字节存储,内部运算类型为整型
CREATE TABLE test(
c1 DATE,
c2 TIMESTAMP);

三、SYSDATE

  • 其本质是一个Oracle的内部函数,返回当前的系统时间,精确到秒
  • 默认显示格式是DD-MON-RR

四、SYSTIMESTAMP

  • 内部函数,返回当前系统日期和时间,精确到毫秒

五、日期转换函数
1.TO_DATE·

  • TO_DATE(char[, fmt[,nlsparams]]):将字符串按照定制格式转换为日期类型
  • char:要转换的字符串
  • fmt:格式
  • nlsparams:指定日期语言
YY 2位数字的年份
YYYY 4为数字的年份
MM 2位数字的月份
MON 简拼的月份
MONTH 全拼的月份
DD 2位数字的天
DY 周几的缩写
DAY 周几的全拼
HH24 24小时制的小时
HH12 12小时制的小时
MI 显示分钟
ss 显示秒

2.TO CHAR

  • 将其它类型的数据转换为字符类型
  • TO_CHAR(date[, fmt[, nlsparams]]):将日期类型数据date按照fmt的格式输出字符串。nlsparams用于指定日期语言
  • 需要注意的是,fmt格式字符串中出现汉字或其他非符号字符时需要用双引号。
SELECT ename,
TO_CHAR(hiredate, 'YYY"年" MM"月"DD"日"')
FROM emp;

六、日期常用函数
1.LAST DAY

  • LAST_DAY(date):返回日期date所在月的最后一天
  • 在按照自然月计算某些业务逻辑,或者安排月末周期性活动时很有用处

2.ADD MONTHS

  • ADD_MONTHS(date, i):返回日期date加上i个月后的日期值
  • 参数i可以是任何数字,大部分时候取正值整数
  • 如果i是小数,将会被截取整数后再参与运算
  • 如果i是负数,则获得的是减去i个月后的日期值

3.MONTHS BETWEEN

  • MONTH_BETWEEN(date1, date2):计算date1和date2两个日期值之间间隔了多少个月
  • 实际运算是date1-date2,如果date2时间比date1晚,会得到负值
  • 除非两个日期间隔是整数月,否则会得到带小数位的结果,比如计算2009年9月1日到2009年10月10日之间间隔多少个月,会得到1.29个月

4.NEXT DAY

  • NEXT_DAY(date, char):返回date日期数据的下一个周几,周几是由参数char来决定的
  • 在中文环境下,直接使用”星期三”这种形式,英文环境下,需要使用”WEDNESDAY”这种英文的周几。为避免麻烦,可以直接用数字1-7表示周日-周六
  • NEXT_DAY不是明天!

5.LEAST、GREATEST

  • GREATEST(expr1[, expr2[, expr3]]…)
  • LEAST(expr1[, expr2[, expr3]]…)
  • 也被称作比较函数,可以有多个参数值,返回结果是参数列表中最大或最小的值
  • 参数类型必须一致
  • 在比较之前,在参数列表中第二个以后的参数会被隐含的转换为第一个参数的数据类型,所以如果可以转换,则继续比较,如果不能转换将会报错
SELECT LEAST(SYSDATE, '10-10月-08') FROM DUAL;

空值和空值函数

一、NULL的含义

  • 数据库里的重要概念: NULL,即空值
  • 有时表中的某些字段值,数据未知或暂时不存在,取值NULL
  • 任何数据类型均可取值NULL
  • 任何数与NULL进行结算结界都为NULL

二、NULL条件查询

  • NULL不等于任何值
SELECT * FROM student WHERE gender IS NULL;

三、非空约束

  • 非空(NOT NULL)约束用于确保字段值不为空
  • 默认情况下,任何列都允许有空值,但系统的业务逻辑可能会要求某些列不能取空值
  • 当某个字段被设置了非空约束条件,这个字段中必须存在有效值。即:当执行插入数据的操作时,必须提供这个列的数据,当执行更新操作时,不能给这个列的值设置为NULL
CREATE TABLE student
(id NUMBER(4),
name CHAR(20),
gender CHAR(1) NOT NULL);

四、空值函数
1.NVL

  • NVL(expr1,expr2):将NULL转变为非NULL值
  • 如果expr1为NULL,则取值expr2, expr2是实际值
  • expr1和expr2可以是任何数据类型,但两个参数的数据类型必须是一致的

2.NVL2

  • NVL2(expv1, expr2, expr3):和NVL函数功能类似,都是将NULL转变为实际值
  • NVL2用来判断expr1是否为NULL,如果不是NULL,返回expr2,如果是NULL,返回expr3。

基本查询语句

一、FROM子句

SELECT <*, column [alias], ...> FROM table;
  • SELECT用于指定要查询的列
  • FROM指定要从哪个表中查询

二、使用别名

  • 在SQL语句中可以通过使用列的别名改变标题的显示样式,或者表示计算结果的含义
  • 使用语法是列的别名跟在列名后,中间可以加或不加一个“AS”关键字
  • 如果希望别名中区分大小写字符,或者别名中包含字符或空格,则必须用双引号引起来

三、WHERE子句

  • 在SELECT语句中,可以在WHERE子句中使用比较操作符限制查询结果
  • 如果和数字比较,可以使用单引号引起,也可以不用
  • 如果和字符及日期类型的数据比较,则必须用单引号引起
  • 使用><, >=,<=, =,<>,=
--查询职员表中薪水低于2000元的职员信息
SELECT ename, sal FROM emp
WHERE sal < 2000;
--查询职员表中不属于部门10的员工信息(!=等价于<>)
SELECT ename, sal, job FROM emp
WHERE deptno != 10;
--查询职员表中在2002年1月1号以后入职的职员信息,比较日期类型数据
SELECT ename, sal, hiredate FROM emp
WHERE hiredate > to_date('2002-1-1','YYYY-MM-DD');

四、使用AND ,OR关键字

  • 在SQL操作中,如果希望返回的结果必须满足多个条件,应该使用AND逻辑操作符连接这些条件
  • 在SQL操作中,如果希望返回的结果满足多个条件之一即可,应该使用OR逻辑操作符连接这些条件。

五、使用LIKE条件(模糊查询)

  • 比较操作符LIKE用来做模糊查询
  • 当用户在执行查询时,不能完全确定某些信息的查询条件,或者只知道信息的一部分,可以借助LIKE来实现
  • LIKE需要借助两个通配符:
    %:表示0到多个字符
    _:标识单个字符
  • 这两个通配符可以配合使用,构造灵活的匹配条件
SELECT ename, job FROM emp
WHERE ename LIKE'_A%;

六、使用IN和NOT IN

  • 比较操作符IN(list)用来取出符合列表范围中的数据
  • List表示值列表,当列或表达式匹配于列表中的任何一个值时,条件为TRUE,该条记录则被显示出来
  • IN也可以理解为一个范围比较操作符,只不过这个范围是一个指定的值列表
  • NOT IN(list)取出不符合此列表中的数据记录
--查询职位是MANAGER或者CLERK的员工
SELECT ename, job FROM emp
WHERE job IN ('MANAGER','CLERK");--查询不是部门10或20的员工
SELECT ename, job FROM emp WHERE deptno NOT IN (10,20);

七、BETWEEN…AND…

  • BETWEEN…AND…操作符用来查询符合某个值域范围条件的数据
  • 最常见的是使用在数字类型的数据范围上,但对字符类型和日期类型数据也同样适用

八、使用IS NULL和IS NOT NULL

  • 空值NULL是一个特殊的值,比较的时候不能使用”=”号,必须使用IS NULL,否则不能得到正确的结果。

九、使用ANY和ALL条件

  • ALL和ANY不能单独使用,需要配合单行比较操作符>、>=、<、<=一起使用
> ANY:大于最小
< ANY:小于最大
> ALL:大于最大
> <ALL:小于最小
--例子
SELECT empno, ename, job, sal, deptnoFROM emp
WHERE sal> ANY (3500,4000,4500);

十、查询条件中使用表达式和函数

  • 当查询需要对选出的字段进行进一步计算,可以在数字列上使用算术表达式(+、-、*、)
  • 表达式符合四则运算的默认优先级,如果要改变优先级可以使用括号
  • 算术运算主要是针对数字类型的数据,对日期类型的数据可以做加减操作,表示在一个日期值上加或减一个天数
--查询条件中使用函数
select ename, sal, job from emp where ename = UPPER('rose');
--查询条件中使用表达式
select ename, sal, job from emp where sal * 12 >100000;

去重与排序

一、使用DISTINCT过滤重复

  • 数据表中有可能存储相同数据的行,当执行查询操作时,默认情况会显示所有行,不管查询结果是否有重复数据
  • 当重复数据没有实际意义,经常会需要去掉重复值,使用DISTINCT实现
--查询员工的部门编码
SELECT deptno FROM emp;
--查询员工的部门编码,去掉重复值
SELECT DISTINCT deptno FROM emp;
--查询每个部门的职位,去掉重复值
SELECT DISTINCT deptno, job FROM emp;

二、排序
1.使用ORDER BY 子句

  • 对数据按一定规则进行排序操作,使用ORDER BY子句
SELECT <*, column [alias], ...>
FROM table
[WHERE condition(s)]
[ORDER BY column [ASC |DESC]];
  • 必须出现在SELECT中的最后一个子句
  • ASC用来指定升序排序(默认选项),DESC用来指定降序排序
  • NULL值视作最大,则升序排列时,排在最后,降序排列时,排在最前
  • 不写ASC或DESC,默认是ASC,升序排列
SELECT empno, ename, mgr FROM emp
WHERE deptno = 10 ORDER BY mgr;

降序排列,必须指明

SELECT ename, sal FROM emp
ORDER BY sal DESC;

2.多个列排序

  • 当以多列作为排序标准时,首先按照第一列进行排序,如果第一列数据相同,再以第二列排序,以此类推
  • 多列排序时,不管正序还是倒序,每个列需要单独设置排序方式
--对职员表中的职员排序,先按照部门编码正序排列,再按照薪水降序排列
SELECT ename, deptno, sal FROM emp
ORDER BY deptno ASC, sal DESC;

聚合函数

一、什么是聚合函数

  • 查询时需要做一些数据统计,比如:查询职员表中各部门职员的平均薪水,各部门的员工人数
  • 需要统计的数据并不能在职员表里直观列出,而是需要根据现有的数据计算得到结果
  • 这种功能可以使用聚合函数来实现,即:将表的全部数据划分为几组数据,每组数据统计出一个结果
  • 因为是多行数据参与运算返回一行结果,也称作分组函数、多行函数、集合函数。

二、MAX和MIN

  • 用来取得列或表达式的最大、最小值
  • 可以用来统计任何数据类型,包括数字、字符和日期
--获取机构下的最高薪水和最低薪水,参数是数字
SELECT MAX(sal)max_sal, MIN(sal) min_salFROM emp;
--最早和最晚的入职时间,参数是日期
SELECT MAX(hiredate) max_hire, MIN(hiredate)min_hire
FROM emp;

三、AVG和SUM

  • 用来统计列或表达式的平均值和和值
  • 只能操作数字类型
  • 忽略NULL值
--获得机构下全部职员的平均薪水和薪水总和
SELECT AvG(sal) avg_sal, SuM(sal) sum_sal FROM emp;

四、COUNT

  • 用来计算表中的记录条数
  • 忽略NULL值
--获取职员表中一共有多少名职员记录
SELECT COUNT(*) total num FROM emp;
--获得职员表中有多少人是有职位的(忽略没有职位的员工记录)
SELECT COUNT(job) total job FROM emp;

分组

一、GROUP BY子句

SELECT <*, column [alias], ....>
FROM table [WHERE condition(s)]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column [ASC | DESC]] ;
  • 当希望得到每个部门的平均薪水,而不是整个机构的平均薪水
  • 把整个数据表按部门划分成一个个小组,每个小组中包含一行或多行数据,在每个小组中再使用分组函数进行计算,每组返回一个结果
  • 划分的小组有多少,最终的结果集行数就有多少

二、HAVING子句

  • HAVING子句用来对分组后的结果进一步限制,比如按部门分组后,得到每个部门的最高薪水,可以继续限制输出结果
  • 必须跟在GROUP BY后面,不能单独存在
--查询每个部门的最高薪水,只有最高薪水大于4000的记录才被输出显示
SELECT deptno,MAX(sal) max_sal FROM empGROUP BY deptno HAVING MAX(sal) >4000;

关联查询

一、关联的概念

  • 实际应用中所需要的数据,经常会需要查询两个或两个以上的表
  • 这种查询两个或两个以上数据表或视图的查询叫做连接查询
  • 连接查询通常建立在存在相互关系的父子表之间
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2;

二、笛卡尔积

  • 笛卡尔积指做关联操作的每个表的每一行都和其它表的每一行做组合,假设两个表的记录条数分别是X和Y,笛卡尔积将返回X* Y条记录。
  • 关联查询时不指定连接条件就会出现笛卡尔积,实际开发中要避免这种情况的出现,通常笛卡尔积没有意义。
SELECT COUNT(*)FROM emp;--14条记录
SELECT COUNT(*)FROM dept; --4条记录
SELECT emp.ename, dept.dname
FROM emp, dept;--56条记录

内连接与外连接

一、内连接

  • 内连接返回所有满足连接条件的记录。
SELECT e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.dep;

--JOIN连接两表,ON连接条件
SELECT e.ename, d.dname
FROM emp e JOIN dept d
ON(e.deptno = d.deptno);

二、外连接

  • 除了将满足连接条件的记录查询出来之外,还可以将不满足连接条件的记录查询出来
--左外连接,以坐标为主表,该表记录都要查询出来,不满足连接条件的记录则来自右刚表的字段值全部为null
SELECT e.ename,e.sal,e.job,e.deptno,d.dname
FROM emp e LEFT OUTER JOIN dept d
ON(e.deptno = d.deptno)

--右外连接
SELECT e.ename,e.sal,e.job,e.deptno,d.dname,d.loc
FROM emp e RIGHT OUTER JOIN dept d
ON(e.deptno = d.deptno)

--全外连接
SELECT e.ename ,e.sal,e.job,e.deptno,d.dname , d.loc
FROM emp e FULL OUTER JOIN dept d
ON(e.deptno = d.deptno)

自连接

一、自连接

  • 自连接是一种特殊的连接查询,数据的来源是一个表,即关联关系来自于单表中的多个列
  • 表中的列参照同一个表中的其它列的情况称作自参照表
  • 自连接是通过将表用别名虚拟成两个表的方式实现,可以是等值或不等值连接
--查看公司每个员工的名字以及其领导的名字
SELECT e.ename , m.ename
FROM emp e, emp m
WHERE e.mgr=m.empno

--
SELECT e.ename, m.ename
FROM emp e LEET OUTER JOIN emp m
ON(e.mgr=m.empno)

子查询

一、子查询在WHERE子句中

  • 在SELECT查询中,在WHERE查询条件中的限制条件不是一个确定的值,而是来自于另外一个查询的结果
  • 为了给查询提供数据而首先执行的查询语句叫做子查询子查询是嵌入在其它SQL语句中的SELECT语句,大部分时候出现在WHERE子句中
  • 子查询嵌入的语句称作主查询或父查询
  • 主查询可以是SELECT语句,也可以是其它类型的语句比如DML或DDL语句
  • 根据返回结果的不同,子查询可分为单行子查询、多行子查询及多列子查询
--查找和SCOTT同职位的员工: 先执行子查询,得到结果后再进行主查询
SELECT e.ename, e.job
FROM emp e
WHERE e.job =
(SELECT job FROM emp WHERE ename = 'SCOTT');
--查找薪水比整个机构平均薪水高的员工
SELECT deptno, ename, sal
FROM emp e
WHERE sal> (SELECT AVG(sal) FROM emp;

二、如果子查询返回多行,主查询中要使用多行比较操作符

  • 多行比较操作符包括lN、ALL、ANY。其中ALL和ANY不能单独使用,需要配合单行比较操作符>、>=、<、<=一起使用
--查询出部门中有SALESMAN但职位不是SALESMAN的员工的信息:子查询的结果是多个值
SELECT empno, ename, job.sal, deptno
FROM emp
WHERE deptno lN
(SELECT deptno FROM emp WHERE job = 'SALESMAN'")
AND job <> 'SALESMAN';

三、在子查询中需要引用到主查询的字段数据

  • 使用EXISTS关键字
  • EXISTS后边的子查询至少返回一行数据,则整个条件返回TRUE。
--列出来那些有员工的部门信息
SELECT deptno, dname FROM dept d
WHERE EXISTS
(SELECT * FROM emp e
WHERE d.deptno = e.deptno);

四、子查询在HAVING子句中

--查询列出最低薪水高于部门30的最低薪水的部门信息
SELECT deptno,MIN(sal) min_sal
FROM emp
GROUP BY deptno
HAVING MIN(sal)>
(SELECT MIN(sal) FROM emp WHERE deptno = 30);

五、子查询在FROM部分

  • FROM子句用来指定要查询的表
  • 如果要在一个子查询的结果中继续查询,则子查询出现在FROM子句中,这个子查询也称作行内视图或者匿名视图
  • 把子查询当作视图对待,但视图没有名字,只能在当前的SQL语句中有效
--查询出薪水比本部门平均薪水高的员工信息 子查询当作表一样使用
SELECT e.deptno, e.ename, e.sal
FROM emp e,
(SELECT deptno, AVG(sal) avg sal FROM empGROUP BY deptno) x
WHERE e.deptno = x.deptno
and e.sal > x.avg_sal
ORDER BY e.deptno;

分页查询

一、ROWNUM

  • 被称作伪列,用于返回标识行数据顺序的数字
SELECT ROWNUM, empno, ename, sal
FROM emp;
  • 只能从1计数,不能从结果集中直接截取
SELECT ROWNUM, empno, ename, sal
FROM emp
WHERE rownum <= 3;
--ROWNU是在从表中查询出—条记录时,为该记录在这个字段上生成行号
--因此我们不能在查询过程中使用ROHNUM作为过滤条件
--通过子查询解决

--在分页查询是,我们要确定行号的范围时,可以用如下公式来确定范围
--参数项:1:页数,用n表示第几页   2:每页要显示的条目数,用pageSize表示一页显示多少条记录
--开始行号计算公式:(n-l) *pageSize+l
--结束行号计算公式:pagesize*n
--例如:—页显示20条(pagesize:20)显示第三页(n=3)
--开始行号:(3-1) *20+1    41条开始
--结束行号:20*3           60条结束

DECODE函数

一、DECODE函数基本语法

DECODE (expr,search1, result1[, search2, result2..][default])
  • DECODE用于比较参数expr的值,如果匹配到哪一个search条件,就返回对应的result结果
  • 可以有多组search和result的对应关系,如果任何一个search条件都没有匹配到,则返回最后default的值
  • default参数是可选的,如果没有提供default参数值,当没有匹配到时,将返回NULL。
--查询职员表,根据职员的职位计算奖励金额,当职位分别是’MANAGER’、’ANALYST'、'SALESMAN'时,奖励金额分别是薪水的1.2倍、1.1倍、1.05倍,如果不是这三个职位,则奖励金额取薪水值
SELECT ename, job, sal,
DECODE(job,
'MANAGER',sal * 1.2,
'ANALYST',sal * 1.1,
'SALESMAN',sal * 1.05,
sal
) bonus
FROM emp;
--和DECODE函数功能相似的有CASE语句,实现类似于if-else的操作。
SELECT ename, job, sal,
CASE job 
WHEN 'MANAGER' THEN sal * 1.2
WHEN 'ANALYST' THEN sal * 1.1
WHEN 'SALESMAN' THEN sal * 1.05
ELSE sal END
bonus
FROM emp;

二、DECODE函数在分组查询中的应用

  • 按字段内容分组
  • 场景:计算职位的人数,analyst/manager属于vip,其余是普通员工operation,无法用GROUP BY简单实现
SELECT DECODE(job,
"ANALYST', 'VIP',
'MANAGER','VIP',
'OPERATION') job,
COUNT(1) job_cnt
FROM emp
GROUP BY DECODE(job, 'ANALYST','VIP','MANAGER','VIP, 'OPERATION');
  • 按字段内容排序:
  • 场景:
    Dept表中按”OPERATIONS”.“ACCOUNTING”“SALES”排序,无法按照字面数据排序
SELECT deptno, dname, loc
FROM dept
ORDER BY
DECODE(dname, ' OPERATIONS ',1,' ACCOUNTING',2,'SALES ,3);

排序函数

一、ROW_NUMBER

ROW_NUMBER() OVER(
PARTITION BY col1 ORDER BY col2)
  • 表示根据col1分组,在分组内部根据col2排序
  • 此函数计算的值就表示每组内部排序后的顺序编号,组内连续且唯一
  • Rownum是伪列,ROW_NUMBER功能更强,可以直接从结果集中取出子集
--场景:按照部门编码分组显示,每组内按职员编码排序,并赋予组内编码
SELECT deptno, ename, empno,
ROW_NUMBER()
OVER (PARTITION BY deptno ORDER BY empno)
AS emp_id
FROM emp;

二、RANK

RANK() OVER(
PARTITION BY col1 ORDER BY col2)
  • 表示根据col1分组,在分组内部根据col2给予等级标识
  • 等级标识即排名,相同的数据返回相同排名
  • 跳跃排序,如果有相同数据,则排名相同,比如并列第二,则两行数据都标记为2,但下一位将是第四名
  • 和ROW_NUMBER的区别是有重复值,而ROW_NUMBER没有
--场景:按照部门编码分组,同组内按薪水倒序排序,相同薪水则按奖金数正序排序,并给予组内等级,用Rank ID表示
SELECT deptno, ename, sal, comm,RANK() OVER (PARTITION BY deptno 
ORDER BY sal DESC, comm) "Rank_ID" FROM emp;

三、DENSE RANK

DENSE_RANK() OVER(
PARTITION BY col1 ORDER BY col2)
  • 表示根据col1分组,在分组内部根据col2给予等级标识
  • 即排名,相同的数据返回相同排名
  • 连续排序,如果有并列第二,下一个排序将是三,这一点是和RANK的不同,RANK跳跃排序

集合操作

一、UNION、UNION ALL

  • 为了合并多个SELECT语句的结果,可以使用集合操作符,实现集合的并、交、差
  • 集合操作符包括UNION、UNION ALL、INTERSECT和MINUS
  • 多条作集合操作的SELECT语句的列的个数和数据类型必须匹配
  • ORDER BY子句只能放在最后的一个查询语句中
  • 集合操作的语法如下:
SELECT statement1
[UNION | UNION ALL | INTERSECT |MINUS]
SELECT statement2;

二、UNION、UNION ALL

  • 用来获取两个或两个以上结果集的并集
  • UNION操作符会自动去掉合并后的重复记录
  • UNION ALL返回两个结果集中的所有行,包括重复的行
  • UNION操作符对查询结果排序,UNION ALL不排序
--合并职位是’MANAGER’的员工和薪水大于2500的员工集合,查看两种方式的结果差别
SELECT ename, job, sal FROM emp
WHERE job = 'MANAGER'
UNION
SELECT ename, job, sal FROM emp
WHERE sal >2500;


SELECT ename, job, sal FROM emp
WHERE job = 'MANAGER'
UNION ALL
SELECT ename, job, sal FROM emp
WHERE sal >2500;

三、INTERSECT

  • 获得两个结果集的交集,只有同时存在于两个结果集中的数据,才被显示输出
  • 使用INTERSECT操作符后的结果集会以第一列的数据作升序排列
--显示职位是’MANAGER’的员工和薪水大于2500的员工的交集
SELECT ename, job, sal FROM emp
WHERE job = 'MANAGER'
INTERSECT
SELECT ename, job, sal FROM emp
WHERE sal > 2500;

四、MINUS

  • 获取两个结果集的差集
  • 只有在第一个结果集中存在,在第二个结果集中不存在的数据,才能够被显示出来。也就是结果集一减去结果集二的结果
--列出职位是MANAGER但薪水低于2500的员工记录
SELECT ename, job, sal FROM emp
WHERE job = 'MANAGER'
MINUS
SELECT ename, job, sal FROM emp
WHERE sal >= 2500;

高级分组函数

一、ROLLUP、CUBE和GROUPING SETS

  • ROLLUP、CUBE和GROUPING SETS运算符是GROUP BY子句的扩展,可以生成与使用UNION ALL来组合单个分组查询时相同的结果集,用来简化和高效的实现统计查询
 GROUP BY ROLLUP(a, b, c)
 GROUP BY CUBE(a, b, c)
 GROUP BY GROUPING SETS ( (a), (b))

1.ROLLUP

--假设有表test,有a、b、c、d四个列。
SELECT a,b,c,SUM(d)FROM test GROUP BY ROLLUP(a,b,c)
--等价于:
SELECT a,b.c,SUM(d)FROM test GROUP BY a,b,c
UNION ALL
SELECT a,b,null,SUM(d)FROM test GROUP BY a,b
UNION ALL
SELECT a,null,null,SUM(d)FROM test GROUP BY a
UNION ALL
SELECT null,null,null,sum(d) FROM test

  • 对ROLLUP的列从右到左以一次少一列的方式进行分组直到所有列都去掉后的分组(也就是全表分组)
  • 对于n个参数的ROLLUP,有n+1次分组

2.CUBE

  • GROUP BY CUBE(a, b, c)
  • 对cube的每个参数,都可以理解为取值为参与分组和不参与分组两个值的一个维度,所有维度取值组合的集合就是分组后的集合
  • 对于n个参数的cube,有2^n次分组
  • GROUP BY CUBE(a,b.c),首牛对(a,b,c)进行GROUP BY,然后依次是(a,b),(ac),(a), (b.c),(b),©,最后对全表进行GROUP BY操作,一共是2个3=8次分组

3.GROUPING SETS

  • GROUPING SETS运算符可以生成与使用单个GROUPBY、ROLLUP或CUBE运算符所生成的结果集相同的结果集
  • 如果不需要获得由完备的ROLLUP 或CUBE运算符生成的全部分组,则可以使用GROUPING SETS仅指定所需的分组
  • GROUPING SETS列表可以包含重复的分组

视图

--基于视图查询数据
SELECT empno, ename, sal, deptno FROM v_emp_10

--创建视图
CREATEOR REPLACE VIEw v_emp_10
AS
SELECT empno id , ename name , sal salary ,deptn
FROM emp
WHERE deptno = 10;
DESC v_emp_10
SELECT id, name, salary, deptno FROM v_emp_10

一、对视图进行DML操作

  • 视图本身并不包含数据,只是基表数据的逻辑映射
  • 当对视图执行DML操作时,实际上是对基表的DML操作
  • 对视图执行DML操作的基本原则:
  • 简单视图能够执行DML操作,下列情况除外:在基表中定义了非空列,但简单视图对应的SELECT语句并没有包含这个非空列,导致这个非空列对视图不可见,这时无法对视图执行INSERT操作
  • DELETE操作时,只能删除现有视图里能查到的记录
  • 如果视图定义中包含了函数、表达式、分组语句、DISTINCT关键字或ROWNUM伪列,不允许执行DML操作
  • DML操作不能违反基表的约束条件

二、创建具有CHECK OPTION约束的视图

CREATE [OR REPLACE] VIEW view_name[(alias[, alias...])]
AS subquery
[WITH CHECK OPTION];
  • WITH CHECK OPTION短语表示,通过视图所做的修改,必须在视图的可见范围内
  • 假设INSERT,新增的记录在视图仍可查看
  • 假设UPDATE,修改后的结果必须能通过视图查看到

三、创建具有READ ONLY约束的视图

  • 对简单视图进行DML操作是合法的,但是不安全的
  • 如果没有在视图上执行DML操作的必要,在建立视图时声明为只读来避免这种情况,保证视图对应的基表数据不会被非法修改
CREATE [OR REPLACE] VIEW view_ name[(alias[, alias..])]
AS subquery
[WITH READ ONLY];
CREATE OR REPLACE VIEW v_emp_10
AS
SELECT empno, ename, sal, deptno FROM emp
WHERE deptno = 10
WITH READ ONLY;

--对只读视图执行DML操作,失败
INSERT INTO v_emp_10 VALUES(1258, 'DONNA',3000,10);
--ERROR位于第1行:
--ORA-01733:此处不允许虚拟列
--或:ORA-42399:无法对只读视图执行DML 操作

四、通过查询user_views获取相关信息和视图相关的数据字典:

  • USER_OBJECTS
  • USER_VIEWS
  • 在数据字典USER_OBJECTS中查询所有视图名称
SELECT object_name FROM user_objects
WHERE object type = 'VIEW";

五、创建复杂视图(多表关联)

  • 复杂视图指在子查询中包含了表达式、单行函数或分组函数的视图
  • 必须为子查询中的表达式或函数定义别名
--创建一个视图V_EMP_SALARY,把职员表的数据按部门分组,获得每个部门的平均薪水、薪水总和、最高薪水和最低薪水
CREATE VIEW vemp_salary
AS
SELECT d.dname, avg(e.sal) avg_sal, sum(e.sal) sum_sal,
max(e.sal) max_sal, min(e.sal) min_sal
FROM emp e join dept d
ON e.deptno = d.deptno
GROUP BY d.dname;

六、删除视国

  • 当不再需要视图的定义,可以使用DROP VIEW语句删除视图
    DROP VIEW view_name;
  • 删除视图v_emp_10:
    DROP VIEW v_emp_10;
  • 视图虽然是存放在数据字典中的独立对象,但视图仅仅是基于表的一个查询定义,所以对视图的删除不会导致基表数据的丢失,不会影响基表数据

七、序列
1.什么是序列

  • 序列(SEQUENCE)是一种用来生成唯一数字值的数据库对象
  • 序列的值由Oracle程序按递增或递减顺序自动生成,通常用来自动产生表的主键值,是一种高效率获得唯一键值的途径
  • 序列是独立的数据库对象,和表是独立的对象,序列并不依附于表
  • 通常情况下,一个序列为一个表提供主键值,但一个序列也可以为多个表提供主键值

2.创建序列

CREATE SEQUENCE [schema.]sequence_name
[ START WITH i] [ INCREMENT BY j]
[MAXVALUE m | NOMAXVALUE ]
[ MINVALUE n |NOMINVALUE ]
[ CYCLE | NOCYCLE ][ CACHE p | NOCACHE ]
  • sequence_name是序列名,将创建在schema方案下
  • 序列的第一个序列值是i,步进是j
  • 如果j是正数,表示递增,如果是负数,表示递减

3.序列可生成的最大值是m,最小值是n

  • 如果没有设置任何可选参数,序列的第一个值是1,步进是1
  • CYCLE表示在递增至最大值或递减至最小值之后是否重用序列。若是递减并有最大值,从最大值开始。若是递增并有最小值,从最小值开始。若没有从START WITH指定的值开始。默认是NOCYCLE
  • CACHE用来指定先预取p个数据在缓存中,以提高序列值的生成效率,默认是20

4.使用序列

--创建一个序列,起始数据是100,步进是10
--当序列被创建后,第一个序列值将是100,将要生成的序列号分别是110、120、130等
CREATE SEQUENCE emp seq
START WITH 100
INCREMENT BY 10;
  • 序列中有两个伪列
  • NEXTVAL:获取序列的下个值
  • CURRVAL:获取序列的当前值
  • 当序列创建以后,必须先执行一次NEXTVAL,之后才能使用CURRVAL
  • 获取序列的第一个值,并且使用序列值为EMP表插入新的记录。
SELECT emp_seq.NEXTVAL FROM DUAL;
INSERT INTO emp(empno, ename)
VALUES(emp_seq.NEXTVAL, 'donna');
  • 查询刚刚生成的记录,主键值将是10
SELECT empno, ename FROM emp
WHERE ename = 'DONNA';
  • 此时查询序列的当前值,会得到110的数字。
SELECT emp_seq.CURRVAL FROM DUAL;
  • 在序列的使用过程中,比如执行了一条SELECT
    emp_seq.NEXTVAL FROM DUAL语句,则浪费了一个序列值,会导致表的主键值不连续。而CURRVAL的使用不会导致序列值的递进

5.删除序列

  • 删除序列的语法如下:
    DROP SEQUENCE sequence_name;
  • 删除序列emp_seq。
    DROP SEQUENCE emp_seq;

索引

一、索引的原理

  • 索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是独立于表的对象,可以存放在与表不同的表空间(TABLESPACE)中
  • 索引记录中存有索引关键字和指向表中数据的指针(地址)
  • 对索引进行的I/O操作比对表进行操作要少很多
  • 索引一旦被建立就将被Oracle系统自动维护,查询语句中不用指定使用哪个索引
  • 索引是一种提高查询效率的机制
  • Oracle B-tree索引的结构
  • ROWID:伪列,唯一标识一条数据记录,可理解为行地址

二、创建索引
创建索引的语法:

CREATE [UNIQUE] INDEX index_name
ON table(column[, column.]);
-- index_name表示索引名称
-- table表示表名
-- column表示列名,可以建立单列索引或复合索引
-- UNIQUE表示唯一索引
  • 在EMP表的ENAME列上建立索引
CREATE INDEX idx_emp_ ename ON emp(ename);
  • 复合索引也叫多列索引,是基于多个列的索引
  • 如果经常在ORDER BY子句中使用job和sal作为排序依据,可以建立复合索引:
CREATE INDEX idx emp job_sal ON emp(job, sal);
  • 当做下面的查询时,会自动应用索引idx_emp_job_sal
SELECT empno, ename, sal, job FROM emp
ORDER BY job, sal;

三、创建基于函数的索引 。

  • 如果需要在emp表的ename列上执行大小写无关搜索,可以在此列上建立一个基于UPPER函数的索引:
CREATE INDEX emp_ename_upper_idx
ON emp(UPPER(ename));
  • 当做下面的查询时,会自动应用刚刚建立的索引引:
SELECT * FROM emp
WHERE UPPER(hame)= 'KING";

四、修改和删除索引

  • 如果经常在索引列上执行DML操作,需要定期重建索引,提高索引的空间利用率:
ALTER INDEX index name REBUILD;
  • 重建索引idx_ emp ename
ALTER INDEX idx emp ename REBUILD;
  • 当一个表上有不合理的索引,会导致操作性能下降,删除索引的语法:
    DROP INDEX index_name;
  • 删除索引idx_emp_ename
    DROP INDEX idx_ emp ename;

五、合理使用索引提升查诲效率

  • 为经常出现在WHERE子句中的列创建索引
  • 为经常出现在ORDER BY、DISTINCT后面的字段建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致
  • 为经常作为表的连接条件的列上创建索引
  • 不要在经常做DML操作的表上建立索引
  • 不要在小表上建立索引
  • 限制表上的索引数目,索引并不是越多越好
  • 删除很少被使用的、不合理的索引

约束

一、约束的作用

  • 约束(CONSTRAINT)的全称是约束条件,也称作完整性约束条件
  • 约束是在数据表上强制执行的一些数据校验规则,当执行DML操作时,数据必须符合这些规则,如果不符合则无法执行
  • 约束条件可以保证表中数据的完整性,保证数据间的商业逻辑

二、约束的类型

  • 约束条件包括:
  • 非空约束(Not Null),简称NN
  • 唯一性约束(Unique),简称UK
  • 主键约束(Primary Key),简称PK
  • 外键约束(Foreign Key),简称FK
  • 检查约束(Check),简称CK

三、非空约束
1.建表时添加非空约束

  • 非空约束用于确保字段值不为空
  • 默认情况下,任何列都允许有空值,但业务逻辑可能会要求某些列不能取空值
  • 当某个字段被设置了非空约束条件,这个字段中必须存在有效值,即:
  • 当执行INSERT操作时,必须提供这个列的数据
    -当执行UPDATE操作时,不能给这个列的值设置为NULL

2.修改表时添加非空约束

  • 可以在建表之后,通过修改表的定义,添加非空约束:
ALTER TABLE employees
MODIFY (eid NUMBER(6) NOT NULL);

3.取消非空约束

  • 如果业务要求取消某列的非空约束,可以采用重建表或者修改表的方式:
ALTER TABLE employees
MODIFY (eid NUMBER(6) null):

四、唯一性约束
1.什么是唯一性约束

  • 唯一性(Unique)约束条件用于保证字段或者字段的组合不出现重复值
  • 当给表的某个列定义了唯一约束条件,该列的值不允许重复,但允许是NULL值
  • 唯一性约束条件可以在建表同时建立,也可以在建表以后再建立

五、主键约束
1.主键的意义

  • 主键(Primary Key)约束条件从功能上看相当于非空(NUT NULL)且唯一(UNIQUE)的组合
  • 主键字段可以是单字段或多字段组合,即:在主键约束下的单字段或者多字段组合上不允许有空值,也不允许有重复值
  • 主键可以用来在表中唯一的确定一行数据
  • 一个表上只允许建立一个主键,而其它约束条件则没有明确的个数限制

2.主键选取的原则

  • 主键应是对系统无意义的数据
  • 永远也不要更新主键,让主键除了唯一标识一行之外,再无其他的用途
  • 主键不应包含动态变化的数据,如时间戳
  • 主键应自动生成,不要人为干预,以免使它带有除了唯一标识一行以外的意义
  • 主键尽量建立在单列上

六、外键约束
1.外键约束的意义

  • 外键约束条件定义在两个表的字段或一个表的两个字段上,用于保证相关两个字段的关系

2.添加外键约束

--先建表,在建表后建立外键约束条件
CREATE TABLE employees4(
eid NUMBER(6),
name VARCHAR2(30),
salary NUMBER(7,2),
deptno NUMBER(4)
);
ALTER TABLE employees4
ADD CONSTRAINT employees4_deptno_fk
FOREIGN KEY (deptno) REFERENCES dept(deptno);

3.外键约束对一致性的维护

  • 外键约束条件包括两个方面的数据约束:
  • 从表上定义的外键的列值,必须从主表被参照的列值中选取,或者为NULL;
  • 当主表参照列的值被从表参照时,主表的该行记录不允许被删除。

4.外键约束对性能的降低

  • 如果在一个频繁DML操作的表上建立外键,每次DML操作,都将导致数据库自动对外键所关联的对应表做检查,产生开销,如果已在程序中控制逻辑,这些判断将增加额外负担,可以省去
  • 外键确定了主从表的先后生成关系,有时会影响业务逻辑

5.关联不一定需要外键约束

  • 保证数据完整性可由程序或触发器控制’简化开发,维护数据时不用考虑外键约束大量数
  • DML操作时不需考虑外键耗费时间

七、检查约束
1.什么是检查约束

  • 检查(Check)约束条件用来强制在字段上的每个值都要满足Check中定义的条件
  • 当定义了Check约束的列新增或修改数据时,数据必须符合Check约束中定义的条件

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