Oracle基础

1.文件存储方式保存数据的弊端:
1.缺乏对数据的整体管理,数据不便修改;
2.不利于数据分析和共享
3.数据量急剧增长,大量数据不可能长期保存在文件中。

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

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

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

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

6.DB2数据库概述
DB2是IBM公司的关系型数据库管理系统
DB2有很多不同的版本,可以运行在从掌上产品到大型机不同的终端机器上
DB2 Universal Personal Edition和DB2 Universal Database Workgroup Edition
分别是单用户和多用户系统,可以运行在OS/2和Windows上
DB2是Oracle的主要竞争对手

7.Sybase数据库概述
Sybase是美国Sybase公司的关系型数据库系统
Sybase是较早采用c/s技术的数据库厂商
典型的UNIX或Windows NT平台上客户机/服务器环境下的大型数据库系统
Sybase通常与Sybase SQL Anywhere用于客户机/服务器环境,前者作为服务器数据库,后者为客户机数据库
采用该公司研制的PowerBuilder为开发工具,在国内大中型系统中具有广泛的应用
2010年被SAP收购

8.SQL Server数据库概述
Microsoft SQL Server 是微软的产品,运行在Windows NT服务器上
Microsoft SQL Server 的最初版本适用于中小企业,但是应用范围不断扩展,已经触及到大型、
跨国企业的数据库管理
最新版本是SQL Server 2012

9.MySQL数据库概述
MySQL是开放源代码的小型关系型数据库管理系统,广泛应用在中小型网站中
总体拥有成本低、规模较Oracle和DB2小
2008年1月16日,Sun收购MySQL。2009年4月20日,SUN被Oracle公司收购,所以MySQL现在属于Oracle公司
最新版本:MySQL5.6

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

11.数据定义语言(DDL)
Data Definition Language
用于建立、修改,删除数据库对象
包括:
CREATE:创建表或其他对象的结构
ALTER:修改表或者其他对象的结构
DROP:删除表或其他对象的结构
TRUNCATE:删除表数据,保留表结构

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

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

14.数据查询语言(DQL)
Data Query Language
用来查询所需要的数据
SELECT语句

15.数据控制语言(DCL)
Data Control Language
用于执行权限的授予和收回操作
包括:
GRANT:授予,用于给用户或角色授予权限
REVOKE:用于收回用户或角色已有的权限
CREATE USER:创建用户

16.远程登录数据库服务器
命令行工具:Oracle自带的SQL*PLUS
图形界面工具:SQL Developer

17.使用SQL*PLUS
SQL*Plus是Oracle提供的数据库交互工具
使用广泛,功能强大,方式简单,可以运行在任何Oracle运行的平台上,默认和数据库一起安装
SQL*Plus是一个基于传统的C/S结构的SQL开发工具,客户端和服务器端可以在同一台主机或不同主机上

18.使用Orac SQL Developer
Oracle 官方出品的免费图形化开发工具
便于操作,不必记忆大量的命令,输出结果美观
Java开发的工具,需要指定JDK的位置

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

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

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

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

23.CREATE语句
CREATE TABLE [schema.]table_name(
column_name datatype[DEFAULT expr] [,...]
);

24.DESC语句
DESC table_name;

25.DEFAULT语句
可以通过DEFAULT字句给列指定默认值
给gender列赋默认值‘M‘,如果没有指定性别的员工,默认值是男性

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

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

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

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

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

31.INSERT语句
给数据表增加记录
语法如下:
INSERT INTO table_name[(column[,column...])]
VALUES(value[,value...]);
执行DML操作后,需要再执行commit语句,才算真正确认了此操作
如果插入的列有日期字段,需要考虑日期的格式
默认的日期格式‘DD-MON-RR’
可以自定义日期格式,用TO_DATE函数转换为日期类型的数据

32.UPDATE语句
更新表中的记录
语法如下:
UPDATE table_name
SET column=value[,column=value]...
[WHERE condition];
如果没有WHERE子句,则全表的数据都会被更新,务必小心

33.DELETE语句
删除表中的记录
语法如下:
DELETE [FROM] table_name [WHERE condition];
如果没有WHERE子句,则全表的数据都会被删除!
在DDL语句中的TRUNCATE,同样有删除表数据的作用
和DELETE语句的区别:
DELETE可以有条件删除,TRUNCATE将表数据全部删除
DELETE是DML语句,可以回退,TRUNCATE是DDL语句,立即生效,无法回退
如果是删除全部表记录,且数据量较大,DELETE语句效率比TRUNCATE语句低

1.CHAR和VARCHAR2类型
表示字符串数据类型,用来在表中存放字符串信息,比如姓名、职业,地址等;
CHAR存放定长字符,即存不满补空格;VARCHAR2存放变长字符,存多少占用多少。如保存字符串‘HELLOWORLD‘,共10个英文字母:
CHAR(100):10个字母,补齐90个空格,实际占用100(浪费空间,节省时间)
VARCHAR2(100):10个字母,实际占用10(浪费时间,节省空间)
按照字符的自然顺序排列

2.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个字节

3.CHAR和VARCHAR2的最大长度
CHAR最大取值为2000字节
最多保存2000个英文字符,1000个汉字(GBK)
VARCHAR2最大长度为4000字节
最多保存4000个英文字符,2000个汉字(GBK)
CHAR可以不指定长度,默认为1,VARCHAR2必须指定长度

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

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

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

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

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

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

10.SUBSTR
SUBSTR(char,[m[,n]])
用于获取字符串的子串,返回char中从m位开始取n个字符
如果m=0,则从首字符开始,如果m取负数,则从尾部开始
如果没有设置n,或者n的长度超过了char的长度,则取到字符串末尾为止
字符串的首位计数从1开始

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

12.NUMBER(P)表示整数
完整语法:NUMBER(precision,scale)
如果没有设置scale,则默认取值为0,即NUMBER(p)表示整数
p表示数字的总位数,取值为1-38
用来在表中存放如编码、年龄、次数等用整数记录的数据

13.NUMBER(P,S)表示浮点数
NUMBER(precision,scale)
precision:NUMBER可以存储的最大数字长度(不包括左右两边的0)
scale:在小数点右边的最大数字长度(包括左侧0)
指定了s但是没有指定p,则p默认为38,如:列名 number(*,s)
经常用来做表中存放金额、成绩等有小数位的数据

NUMBER的变种数据类型:内部实现是NUMBER,可以将其理解为NUMBER的别名,目的是多种数据库及编程语言兼容
NUMBER(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类型

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

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

16.MOD
MOD(m,n):返回m除以n后的余数
n为0则直接返回m

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

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

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

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

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

22.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 显示秒

23.TO_CHAR
将其他类型的数据转换为字符类型
TO_CHAR(date[,fmt[,nlsparams]]):将日期类型数据date按照fmt的格式输出字符串。nlsparams用于指定日期语言

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

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

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

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

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

29.EXTRACT
EXTRACT(date FROM datetime):从参数datetime中提取参数date指定的数据,比如提取年、月、日

30.NULL的含义
数据库里的重要概念:NULL,即空值
有时表中的某些字段值,数据未知或暂时不存在,取值NULL
任何数据类型均可取值NULL

31.更新成NULL值
UPDATE student SET gender=NULL;
注意这种更新只有在此列没有非空约束的情况下才可操作
如果某列有非空约束,则无法更新为NULL值,上述语句会报错

32.NULL条件查询
NULL不等于任何值
SELECT*FROM student WHERE gender IS NULL;(注意是IS,不是=号)

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

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

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

1.FROM字句
SELECT <*,column[alias],...> FROM table;
SELECT用于指定要查询的列
FROM指定要从哪个表中查询
如果要查询所有列,可以在SELECT后面使用*号
如果只查询特定的列,可以直接在SELECT后面指定列名,列名之间用逗号隔开。

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

3.WHERE字句
在SELECT语句中,可以在WHERE字句中使用比较操作符限制查询结果
如果和数字比较,可以使用单引号引起,也可以不用
如果和字符及日期类型的数据比较,则必须用单引号引起

4.SELECT字句
如果只查询表的部分列,需要在SELECT后指定列名
SELECT ename,sal FROM emp;

5.使用>,<,>=,<=,!=,<>,=
查询职员表中薪水低于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‘);

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

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

8.使用IN和NOT IN
比较操作符IN(list)用来取出符合列表范围中的数据
List表示值列表,当列或表达式匹配于列表中的任何一个值时,条件为TRUE,该条记录则被显示出来
IN也可以理解为一个范围比较操作符,只不过这个范围是一个指定的值列表
NOT IN(list)取出不符合此列表中的数据记录

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

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

11.使用ANY和ALL条件
ALL和ANY不能单独使用,需要配合单行比较操作符>,>=,<,<=一起使用
>ANY:大于最小
<ANY:小于最大
>ALL:大于最大
<ALL:小于最小

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

13.使用DISTINCT过滤重复
数据表中有可能存储相同数据的行,当执行查询操作时,默认情况会显示所有行,不管查询结果是否有重复数据
当重复数据没有实际意义,经常会需要去掉重复值,使用DISTINCT实现

14.使用ORDER BY子句
对数据按一定规则进行排序操作,使用ORDER BY子句
SELECT <*,column[alias],...>
FROM table
[WHERE condition(s)]
[ORDER BY column[ASC|DESC]];
必须出现在SELECT中的最后一个子句

15.ASC和DESC
ASC用来指定升序排列(默认选项),DESC用来指定降序排序
NULL值视作最大,则升序排列时,排在最后,降序排列时,排在最前
不写ASC或DESC,默认是ASC,升序排列
降序排列,必须指明

16.多个列排序
当以多列作为排序标准时,首先按照第一列进行排序,如果第一列数据相同,再以第二列排序,依次类推
多列排序时,不管正序还是倒序,每个列需要单独设置排序方式

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

18.MAX和MIN
用来取得列或表达式的最大、最小值
可以用来统计任何数据类型,包括数字、字符和日期

19.AVG和SUM
用来统计列或表达式的平均值和和值
只能操作数字类型
忽略NULL值

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

21.聚合函数对空值的处理
聚合函数忽略NULL值
当emp表中的comm列有NULL值,比如某新入职员工没有绩效,比较两条语句的结果:
SELECT AVG(comm) avg_sal FROM emp;
SELECT AVG(NVL(comm,0)) avg_sal FROM emp;

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

23.HAVING子句
HAVING子句用来对分组后的结果进一步限制,比如按部门分组后,得到每个部门的最高薪水,可以继续限制输出结果
必须跟在GROUP BY后面,不能单独存在

查询每个部门的最高薪水,只有最高薪水大于4000的记录才被输出显示
SELECT deptno,MAX(sal) max_sal FROM emp
GROUP BY deptno HAVING MAX(sal)>4000;

24.查询语句执行顺序
查询语句的执行顺序依下列子句次序:
1.from子句:执行顺序为从后往前、从右到左
数据量较少的表尽量放在后面
2.where子句:执行顺序为至下而上、从左到右
将能过滤掉最大数量记录的条件写在Where子句的最右
3.groub by--执行顺序从左往右分组
最好在GROUP BY前使用WHERE将不需要的记录在GROUP BY之前过滤掉
4.having子句:消耗资源
尽量避免使用,HAVING会在检索出所有记录之后才对结果集进行过滤,需要排序等操作
5.select子句:少用*号,尽量取字段名称
ORACLE在解析的过程中,通过查询数据字典将*号依次转换成所有的列名,消耗时间
6.order by子句:执行顺序为从左到右排序,消耗资源

25.关联的概念
实际应用中所需要的数据,经常会需要查询两个或两个以上的表
这种查询两个或两个以上数据表或视图的查询叫做连接查询
连接查询通常建立在存在相互关系的父子表之间

SELECT table1.column,table2.column
FROM table1,table2
WHERE table1.column1=table2.column2;

26.笛卡尔积
笛卡尔积指做关联操作的每一表的每一行都和其他表的每一行做组合,假设两个表的记录条数分别是X和Y,笛卡尔积将返回X*Y条记录

27.等值连接
连接查询中最常见的一种,通常是在有主外键关联关系的表间建立,并将连接条件设定为有关系的列,使用等号"="连接相关的表

28.内连接
内连接返回所有满足连接条件的记录

SELECT e.ename,d.dname
FROM emp e,dept d
WHERE e.deptno=d.deptno;

SELECT e.ename,d.name
FROM emp e JOIN dept d
ON(e.deptno=d.deptno);

29.外连接
内连接返回满足连接条件的数据记录
有些情况,需要返回那些不满足连接条件的记录,需要使用外连接
外连接不仅返回满足连接条件的记录,还将返回不满足连接条件的记录
驱动表概念

SELECT table.column,table2.column
FROM table1 LEFT|RIGHT|FULL [OUTER] JOIN table2
ON table1.column1=table2.column2;

emp表做驱动表
SELECT e.ename,d.dname
FROM emp e LEFT OUTER JOIN dept d
ON e.deptno=d.deptno;
dept表做驱动表
SELECT e.ename,d.dname
FROM emp e RIGHT OUTER JION dept d
ON e.deptno=d.deptno;

30.全外连接
全外连接是指,除了返回满足连接条件的记录,还会返回不满足连接条件的所有其他行
是左外连接和右外连接查询结果的总和

SELECT e.ename,d.dname
FROM emp e FULL OUTER JOIN dept d
ON e.deptno=d.deptno;

31.自连接
自连接是一种特殊的连接查询,数据的来源是一个表,即关联关系来自于单表中的多个列
表中的列参照同一个表中的其他列的情况称作自参照表
自连接是通过将表用别名虚拟成两个表的方式实现,可以是等值或不等值连接

查出每个职员的经理名字,以及他们的职员编码
SELECT worker.empno w_empno,worker.ename w_ename,manager.empno m_empno,manager.ename m_ename
FROM emp worker join emp manager
ON worker.mgr=manager.empno;

1.子查询在WHERE子句中
在SELECT查询中,在WHERE查询条件中的限制不是一个确定的值,而是来自于另外一个查询的结果
为了给查询提供数据而首先执行的查询语句叫做子查询
子查询是嵌入在其他SQL语句中的SELECT语句,大部分时候出现在WHERE子句中
子查询嵌入的语句称作主查询或父查询
主查询可以是SELECT语句,也可以是其它类型的语句比如DML或DDL语句

根据返回结果的不同,子查询可分为单行子查询,多行子查询及多列子查询

如果子查询返回多行,主查询中要使用多行比较操作符
多行比较操作符包括IN,ALL,ANY。其中ALL和ANY不能单独使用,需要配合单行比较操作符>、>=、<、<=一起使用
查询出部门中有SALESMAN但职位不是SALESMAN的员工信息
SELECT empno,ename,job,sal,deptno
FROM emp
WHERE deptno IN
(SELECT deptno FROM emp WHERE job=‘SALESMAN‘)
AND job<>‘SALESMAN‘;

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

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

3.子查询在FROM部分
FROM子句用来指定要查询的表
如果要在一个子查询的结果中继续查询,则子查询出现在FROM子句中,这个子查询也称作行内视图或者匿名视图
把子查询当作视图对峙,但视图没有名字,只能在当前的SQL语句中有效

查询出薪水比本部门平均薪水高的员工信息
SELECT e.deptno,e.ename,e.sal
FROM emp e,
(SELECT deptno,AVG(sal) avg_sal FROM emp GROUP BY deptno) x
WHERE e.deptno=x.deptno
and e.sal>x.avg_sal
ORDER BY e.deptno;

4.子查询在SELECT部分
把子查询放在SELECT子句部分,可以认为是外连接的另一种表现形式,使用更灵活
SELECT e.ename,e.sal,
(SELECT d.deptno FROM dept d
WHERE d.deptno=e.deptno) deptno
FROM emp e;

5. ROWNUM
被称作伪列,用于返回标识行数据顺序的数字
SELECT ROWNUM,empno,ename,sal
FROM emp;
只能从1计数,不能从结果集中直接截取
SELECT ROWNUM,empno,ename,sal
FROM emp
WHERE rownum>3;(查询不到结果)
利用ROWNUM截取结果集中的部分数据,需要用到行内视图
SELECT * FROM
(SELECT ROWNUM rn,e.*FROM emp e)
WHERE rn BETWEEN 8 AND 10;

6.使用子查询进行分页
分页策略:每次只取一页的数据。每次换页,取下一页的数据。
在ORACLE中利用ROWNUM的功能可用来进行分页
假设结果集共105条,每20条分为一页,则:
Page1: 1至20
Page2: 21至40
...
Page3: (n-1)*pageSize+1至n*pageSize

7.分页与ORDER BY
按薪水倒序排列,取出结果集中第8到第10条的记录
SELECT * FROM
(SELECT ROWNUM rn,t.*FROM
(SELECT empno,ename,sal,FROM emp ORDER BY sal DESC) t
)
WHERE rn BETWEEN 8 AND 10;
根据要查看的页数,计算起点值((n-1)*pageSize+1)和终点值(n*pageSize),替换掉BETWEEN和AND
的参数,即得到当前页的记录

8.DECODE函数基本语法
DECODE(expr,search1,result1[,serch2,result2...][,default])
DECODE用于比较参数expr的值,如果匹配到哪一个search条件,就返回对应的result结果
可以有多组search和result的对应关系,如果任何一个search条件都没有匹配到,则返回最后default的值
default参数是可选的,如果没有提供default参数值,当没有匹配到时,将返回NULL。

和DECODE函数功能相似的有CASE语句,实现类似于if-else的操作。
SELECT ename,job,sal,
CASE job WHERE ‘MANAGER‘ THEN sal*1.2
WHERE ‘ANALYST‘ THEN sal*1.1
WHERE ‘SALESMAN‘ THEN sal*1.05
ELSE sal END
bonus
FROM emp;

9.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);

10.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;

11.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;

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

场景:关联emp和dept表,按照部门编码分组,每组内按照员工薪水排序,列出员工部门名字、姓名和薪水
SELECT d.dname,e.ename,e.sal,
DENSE_RANK() OVER(PARTITION BY e.deptno ORDER BY e.sal)
AS drank
FROM emp e join dept d
on e.deptno=d.deptno;

13.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不排序

合并职位是‘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;

14.INTERSECT
获得两个结果集的交集,只有同时存在于两个结果集中的数据,才被显示输出
使用INTERSECT操作符后的结果集会以第一列的数据作升序排列

15.MINUS
获取两个结果集的差集
只有在第一个结果集中存在,在第二个结果集中不存在数据,才能够被显示出来。也就是结果集一减去结果集二的结果

16.ROLLUP
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))

假设有表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次分组

17.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),(a,c),(a),(b,c),(b),(c),最后对全表进行GROUP BY操作,一共是2^3=8次分组

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

分组示例:
使用GROUP BY GROUPING SETS(a,b,c),则对(a),(b),(c)进行GROUP BY
使用GROUP BY GROUPING SETS((a,b),c),则对(a,b),(c)进行GROUP BY
使用GROUP BY GROUPING SETS(a,a),则对(a)进行2次GROUP BY,GROUPING SETS的参数允许重复

什么是视图
视图(VIEW)也被称作虚表,即虚拟的表,是一组数据的逻辑表示
视图对应于一条SELECT语句,结果集被赋予一个名字,即视图名字
视图本身并不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发生变化,视图数据也随之变化

CREATE [OR REPLACE] VIEW view_name[(alias[,alias...])] AS subquery;
视图创建后,可以像操作表一样操作视图,主要是查询
Subquery是SELECT查询语句,对应的表被称作基表
根据视图所对应的子查询种类分为几种类型
SELECT 语句是基于单表建立的,且不包含任何函数运算、表达式或分组函数,叫做简单视图,此时视图是基表的子集
SELECT语句同样是基于单表,但包含了单行函数、表达式、分组函数或GROUP BY子句,叫做复杂视图
SELECT语句是基于多个表的,叫做连接视图

2.视图的作用
如果需要经常执行某项复杂查询,可以基于这个复杂查询建立视图,此后查询此视图即可,简化复杂查询
视图本质是就是一条SELECT语句,所以当访问视图时,只能访问到所对应的SELECT语句中涉及到的列,
对基表中的其他列起到安全和保密的作用,限制数据访问

3.授权创建视图
创建视图的语句是CREATE VIEW
用户必须有CREATE VIEW系统权限,才能创建视图
如果没有权限,会提示:权限不足
管理员可以通过DCL语句授予用户创建视图的权限:
GRANT CREATE VIEW TO tarena;
GRANT...TO...(DCL命令,授予权限)
CREATE VIEW 授予何种权限
tarena权限赋予给谁

4.创建简单视图(单表)
创建一个简单视图V_EMP_10来显示部门10中的员工的编码、姓名和薪水
CREATE VIEW v_emp_10
AS
SELECT empno,ename,sal,deptno
FROM emp
WHERE deptno=10;
查看视图结构:
DESC v_emp_10;

创建视图时,给列赋予别名
可以用OR REPLACE短语修改视图对应的SQL查询语句
CREATE OR REPLACE VIEW v_emp_10
AS
SELECT empno id,ename name,sal salary,deptno
FROM emp
WHERE deptno=10;
检查视图结构
DESC v_emp_10;

5.查询视图
查询视图和查询表的操作相同:
SELECT * FROM v_emp_10;
此时视图的列名,和创建视图时的列名一致,不一定是原列名:
SELECT id,name,salary FROM v_emp_10;

6.对视图进行INSERT操作
视图本身并不包含数据,只是基表数据的逻辑映射
当对视图执行DML操作时,实际上是对基表的DML操作
对视图执行DML操作的基本原则:
简单的视图可以执行DML操作,下列情况除外;在基表中定义了非空列,但简单视图对应的SELECT语句
并没有包含这个非空列,导致这个非空列对视图不可见,这时无法对视图执行INSERT操作
如果视图定义中包含了函数、表达式、分组语句、DISTINCT关键字或ROWNUM伪列,不允许执行DML操作
DML操作不能违反基表的约束条件
对简单视图执行INSERT操作,成功插入数据到基表中
INSERT INTO v_emp_10
VALUES(1234,‘DOCTOR‘,4000,10);
简单视图可以通过DML操作影响到基表数据

7.创建具有CHECK OPTION约束的视图
CREATE [OR REPALCE] VIEW view_name[(alias[,alias...])]
AS subquery
[WITH CHECK OPTION];

WITH CHECK OPTION短语表示,通过视图所做的修改,必须在视图的可见范围内
假设INSERT,新增的记录在视图仍可查看
假设UPDATE,修改后的结果必须能通过视图查看到
假设DELETE,只能删除现有视图里能查到的记录

8.创建具有READ ONLY约束的视图
对简单视图进行DML操作是合法的,但是不安全的
如果没有在视图上执行DML操作的必要,在建立视图时声明为只读来避免这种情况,保证视图对应的基表数据不会被非法修改

CREATE [OR REPALCE] VIEW view_name[(alias[,alias...])]
AS subquery
[WITH READ ONLY];

9.通过查询user_views获取相关信息
和视图相关的数据字典:
USER_OBJECTS
USER_VIEWS
USER_UPDATE_COLUMNS
在数据字典USER_OBJECTS中查询所有视图名称
SELECT object_name FROM user_objects
WHERE object_type=‘VIEW‘;
在数据字典USER_VIEWS中查询指定视图
SELECT text FROM user_views
WHERE view_name=‘V_EMP_10‘;
在数据字典中USER_UPDATE_COLUMNS查询视图
SELECT column_name,insertable,updatable,deletable
FROM user_updatable_columns
WHERE table_name=‘V_EMP_10‘;

10.创建复杂视图(多表关联)
复杂视图指在子查询中包含了表达式、单行函数或分组函数的视图
必须为子查询中的表达式或函数定义别名
创建一个视图V_EMP_SALARY,把职员表的数据按部门分组,获得每个部门的平均薪水、薪水总和、最高薪水和最低薪水
CREATE VIEW v_emp_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;

查询复杂视图
SELECT * FORM v_emp_salary;
复杂视图不允许DML操作

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

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

13.创建序列
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是正数,表示递增,如果是负数,表示递减

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

14.使用序列
创建一个序列,起始数据是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‘);

此时查询序列的当前值,会得到110的数字。
SELECT emp_seq.CURRVAL FROM DUAL;
在序列的使用过程中,比如执行了一条SELECT emp_seq.NEXTVAL FROM DUAL语句,则浪费了一个序列值,
会导致表的主键值不连续。而CURRVAL的使用不会导致序列值的递进

15.删除序列
删除序列的语法如下:
DROP SEQUENCE sequence_name;
删除序列emp_seq.
DROP SEQUENCE emp_seq;

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

Oracle B-tree索引的结构
ROWID:伪列,唯一标识一条数据记录,可理解为行地址

17.创建索引
创建索引的语法:
CREATE [UNIQUE] INDEX index_name
ON table(column[,column...]);
index_name表示索引名称
table表示表名
column表示列名,可以建立单列索引或复合索引
UNIQUE表示唯一索引
在EMP表的ENAME列上建立索引
CREATE INDEX idx_emp_name 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;

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

19.修改和删除索引
如果经常在索引列上执行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;

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

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

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

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

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

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

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

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

29.外键约束的意义
外键约束条件定义在两个表的字段或一个表的两个字段上,用于保证相关两个字段的关系
dept表:主表或父表
emp表:从表或子表

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

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

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

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

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。