SQL概述
SQL(Structured Query Language):结构化查询语言,是关系数据库的标准语言
SQL是一个通用的、功能极强的关系数据库语言
一、SQL的特点
1.综合统一
- 集数据定义语言(DDL),数据操纵语言(DML),数据控制语言(DCL)功能于一体。
- 可以独立完成数据库生命周期中的全部活动:
定义关系模式,插入数据,建立数据库;
对数据库中的数据进行查询和更新;
数据库重构和维护
数据库安全性、完整性控制等 - 用户数据库投入运行后,可根据需要随时逐步修改模式,不影响数据的运行。
- 数据操作符统一
2.高度非过程化
- 非关系数据模型的数据操纵语言“面向过程”,必须指定存取路径
- SQL只要提出“做什么”,无须了解存取路径。
- 存取路径的选择以及SQL的操作过程由系统自动完成。
3.面向集合的操作方式
- 非关系数据模型采用面向记录的操作方式,操作对象是一条记录
- SQL采用集合操作方式
操作对象、查找结果可以是元组的集合
一次插入、删除、更新操作的对象可以是元组的集合
4.以同一种语法结构提供多种使用方式
-
SQL是独立的语言
能够独立地用于联机交互的使用方式 -
SQL又是嵌入式语言
SQL能够嵌入到高级语言(例如C,C++,Java)程序中,供程序员设计程序时使用
5.语言简洁,易学易用
二、SQL的基本概念
1.基本表
本身独立存在的表
SQL中一个关系就对应一个基本表
一个(或多个)基本表对应一个存储文件
一个表可以带若干索引
2.存储文件
逻辑结构组成了关系数据库的内模式
物理结构是任意的,对用户透明
3.视图
从一个或几个基本表导出的表
数据库中只存放视图的定义而不存放视图对应的数据
视图是一个虚表
用户可以在视图上再定义视图
学生-课程 数据库
1.学生-课程模式 S-T :
学生表:Student(Sno,Sname,Ssex,Sage,Sdept)
课程表:Course(Cno,Cname,Cpno,Ccredit)
学生选课表:SC(Sno,Cno,Grade)
数据定义
SQL的数据定义功能: 模式定义、表定义、视图和索引的定义
一、模式的定义与删除
1.定义模式
[例1]定义一个学生-课程模式S-T
CREATE SCHEMA “S-T” AUTHORIZATION DING;
为用户DING定义了一个模式S-T
[例2]CREATE SCHEMA AUTHORIZATION DING;
<模式名>隐含为用户名DING
1)定义模式实际上定义了一个命名空间
2)在这个空间中可以定义该模式包含的数据库对象,例如基本表、视图、索引等。
3)在CREATE SCHEMA中可以接受CREATE TABLECREATE VIEW和GRANT子句。
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>[<表定义子句>|<视图定义子句>|<授权定义子句>]
2.删除模式
DROP SCHEMA <模式名> <CASCADE|RESTRICT>
CASCADE(级联)
删除模式的同时把该模式中所有的数据库对象全部删除
RESTRICT(限制)
如果该模式中定义了下属的数据库对象(如表、视图等),则拒绝该删除语句的执行。
当该模式中没有任何下属的对象时才能执行
二、基本表的定义、删除与修改
1.定义基本表
CREATE TABLE <表名>(<列名> <数据类型>[ <列级完整性约束条件> ][,<列名> <数据类型>[ <列级完整性约束条件>] ] …[,<表级完整性约束条件> ] )
如果完整性约束条件涉及到该表的多个属性列,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。
2.数据类型
1)SQL中域的概念用数据类型来实现
2)定义表的属性时 需要指明其数据类型及长度
3)选用哪种数据类型
取值范围
要做哪些运算
3.修改基本表
ALTER TABLE <表名>[ ADD <新列名> <数据类型> [ 完整性约束 ] ][ DROP <完整性约束名> ][ ALTER COLUMN<列名> <数据类型>]
4.删除基本表
DROP TABLE <表名>[RESTRICT| CASCADE]
- RESTRICT:删除表是有限制的。
欲删除的基本表不能被其他表的约束所引用
如果存在依赖该表的对象,则此表不能被删除 - CASCADE:删除该表没有限制。
在删除基本表的同时,相关的依赖对象一起删除
三、索引的建立与删除
1.建立索引的目的
加快查询速度
2.谁可以建立索引
DBA 或 表的属主(即建立表的人)
DBMS一般会自动建立以下列上的索引:PRIMARY KEYUNIQUE
3.谁维护索引
DBMS自动完成
4.使用索引
DBMS自动选择是否使用索引以及使用哪些索引
索引
- RDBMS中索引一般采用B+树、HASH索引来实现
B+树索引具有动态平衡的优点:
普通树:一个结点只有一个关键字;
B树:一个结点有多个关键字;
B树又分为B+树和B-树。
HASH索引具有查找速度快的特点 - 采用B+树,还是HASH索引 则由具体的RDBMS来决定
- 索引是关系数据库的内部实现技术,属于内模式的范畴
- CREATE INDEX语句定义索引时,可以定义索引是唯一索引、非唯一索引或聚簇索引
1.建立索引
CREATE [UNIQUE] [CLUSTER] INDEX <索引名>
ON <表名>(<列名>[<次序>][,<列名>[<次序>] ]…)
1)用<表名>指定要建索引的基本表名字
2)索引可以建立在该表的一列或多列上,各列名之间用逗号分隔
3)用<次序>指定索引值的排列次序,升序:ASC,降序:DESC。缺省值:ASC
4)UNIQUE表明此索引的每一个索引值只对应唯一的数据记录
5)CLUSTER表示要建立的索引是聚簇索引
1)聚簇索引
将数据存储与索引放到了一块,找到索引也就找到了数据。
建立聚簇索引后,基表中数据也需要按指定的聚簇属性值的升序或降序存放。也即聚簇索引的索引项顺序与表中记录的物理顺序一致
2)唯一值索引
对于已含重复值的属性列不能建UNIQUE索引
对某个列建立UNIQUE索引后,插入新记录时DBMS会自动检查新记录在该列上是否取了重复值。这相当于增加了一个UNIQUE约束
2.修改索引
ALTER INDEX <旧索引名> RENAME TO <新索引名>
2.删除索引
DROP INDEX <索引名>
删除索引时,系统会从数据字典中删去有关该索引的描述。
数据查询
对于多表查询,优先顺序:不相关子查询;连接查询;相关子查询;Exist查询
SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>] …
FROM <表名或视图名>[, <表名或视图名> ] …
[WHERE <条件表达式> ]
[ GROUP BY <列名1> [ HAVING <条件表达式> ] ]
[ ORDER BY <列名2> [ ASC|DESC ] ]
- SELECT子句:指定要显示的属性列
- FROM子句:指定查询对象(基本表或视图)
- WHERE子句:指定查询条件
- GROUP BY子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用集函数。
- HAVING短语:筛选出只有满足指定条件的组
- ORDER BY子句:对查询结果表按指定列值的升序或降序排序
一、单表查询
查询仅涉及一个表
1.选择表中的若干列
-
查询指定列
-
选出所有属性列:
在SELECT关键字后面列出所有列名
将<目标列表达式>指定为 * -
查询经过计算的值
SELECT子句的<目标列表达式>可以为:算术表达式、字符串常量、函数、列别名
2.选择表中的若干元组
消除取值重复的行:如果没有指定DISTINCT关键词,则缺省为ALL
查询满足条件的元组
(1) 比较大小
(2)确定范围
谓词: BETWEEN … AND …NOT BETWEEN … AND …
(3) 确定集合
谓词:IN <值表>, NOT IN <值表>
(4)字符匹配
谓词:[NOT] LIKE ‘<匹配串>’ [ESCAPE ‘ <换码字符>’]
<匹配串>:指定匹配模板
匹配模板:固定字符串或含通配符的字符串
当匹配模板为固定字符串时,
可以用 = 运算符取代 LIKE 谓词
用 != 或 < >运算符取代 NOT LIKE 谓词
通配符
- % (百分号) 代表任意长度(长度可以为0)的字符串 eg:a%b表示以a开头,以b结尾的任意长度的字符 串。如acb,addgb,ab
等都满足该匹配串 - _ (下横线) 代表任意单个字符
eg:a_b表示以a开头,以b结尾的长度为3的任意
字符串。如acb,afb等都满足该匹配串
ESCAPE 短语
当用户要查询的字符串本身就含有 % 或 _ 时,要使用ESCAPE ‘<换码字符>’ 短语对通配符进行转义。
字符匹配
- 匹配串为固定字符串
eg:查询学号为200215121的学生的详细情况。 SELECT *
FROM Student WHERE Sno
LIKE(=) ‘200215121';
- 匹配串为含通配符的字符串
eg:查询所有姓刘学生的姓名、学号和性别。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname LIKE ‘刘%’;
- 使用换码字符将通配符转义为普通字符
eg:查询DB_Design课程的课程号和学分。
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design' ESCAPE '\‘;
(5) 涉及空值的查询
谓词:
IS NULL 或 IS NOT NULL
"IS" 不能用 "=" 代替
(6) 多重条件查询
- 逻辑运算符:AND和 OR来联结多个查询条件
AND的优先级高于OR
可以用括号改变优先级 - 可用来实现多种其他谓词
[NOT] IN
[NOT] BETWEEN … AND …
3.ORDER BY子句
1)ORDER BY子句
可以按一个或多个属性列排序
升序:ASC;降序:DESC;缺省值为升序
2)当排序列含空值时
ASC:排序列为空值的元组最后显示
DESC:排序列为空值的元组最先显示
4.聚集函数
计数
COUNT([DISTINCT|ALL] *)
COUNT([DISTINCT|ALL] <列名>)
计算总和
SUM([DISTINCT|ALL] <列名>)
计算平均值
AVG([DISTINCT|ALL] <列名>)
最大最小值
MAX([DISTINCT|ALL] <列名>)
MIN([DISTINCT|ALL] <列名>)
5.GROUP BY子句
GROUP BY子句分组:细化聚集函数的作用对象
未对查询结果分组,聚集函数将作用于整个查询结果
对查询结果分组后,聚集函数将分别作用于每个组
作用对象是查询的中间结果表
按指定的一列或多列值分组,值相等的为一组
HAVING短语与WHERE子句的区别:
作用对象不同
WHERE子句作用于基表或视图,从中选择满足条件的元组
HAVING短语作用于组,从中选择满足条件的组。
二、连接查询
连接查询:同时涉及多个表的查询
连接条件或连接谓词:用来连接两个表的条件
一般格式:
[<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>
[<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>
连接字段:连接谓词中的列名称
连接条件中的各连接字段类型必须是可比的,但名字不必是相同的
- 嵌套循环法(NESTED-LOOP)
➢首先在表1中找到第一个元组,然后从头开始扫描表2,逐一查找满足连接件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。
➢表2全部查找完后,再找表1中第二个元组,然后再从头开始扫描表2,逐一查找满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。
➢ 重复上述操作,直到表1中的全部元组都处理完毕 - 排序合并法(SORT-MERGE):常用于=连接
➢ 首先按连接属性对表1和表2排序
➢ 对表1的第一个元组,从头开始扫描表2,顺序查找
满足连接条件的元组,找到后就将表1中的第一个元
组与该元组拼接起来,形成结果表中一个元组。当
遇到表2中第一条大于表1连接字段值的元组时,对 表2的查询不再继续
➢ 找到表1的第二条元组,然后从刚才的中断点处继续顺序扫描表2,查找满足连接条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。直接遇到表2中大于表1连接字段值的元组时,对表2的查询不再继续
➢ 重复上述操作,直到表1或表2中的全部元组都处理完毕为止 - 索引连接(INDEX-JOIN)
➢ 对表2按连接字段建立索引.
➢ 对表1中的每个元组,依次根据其连接字段值查询表2的索引,从中找到满足条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组.
1.等值与非等值连接查询
等值连接:连接运算符为=
eg:查询每个学生及其选修课程的情况
SELECT Student.*,SC.*
FROM Student,SC
WHERE Student.Sno = SC.Sno;
自然连接:
eg:查询每个学生及其选修课程的情况
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student,SC
WHERE Student.Sno = SC.Sno;
2.自身连接
- 自身连接:一个表与其自己进行连接
- 需要给表起别名以示区别
- 由于所有属性名都是同名属性,因此必须使用别名前缀
3.外连接
外连接与普通连接的区别
➢ 普通连接操作只输出满足连接条件的元组
➢ 外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出
4.复合条件连接
复合条件连接:WHERE子句中含多个连接条件
三、嵌套查询
1. 概述
➢ 一个SELECT-FROM-WHERE语句称为一个查询块
➢ 将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询
➢ 子查询的限制:不能使用ORDER BY子句
➢ 层层嵌套方式反映了 SQL语言的结构化
➢ 有些嵌套查询可以用连接运算替代
2.求解方法
1)不相关子查询:
子查询的查询条件不依赖于父查询
由里向外 逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。
2)相关子查询:
子查询的查询条件依赖于父查询
➢ 首先取外层查询中表的第一个元组,根据它与内层查
询相关的属性值处理内层查询,若WHERE子句返回值
为真,则取此元组放入结果表
➢ 然后再取外层表的下一个元组
➢ 重复这一过程,直至外层表全部检查完为止
-
带有IN谓词的子查询
-
带有比较运算符的子查询
当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或 < > )。
与ANY或ALL谓词配合使用
eg:找出每个学生超过他选修课程平均成绩的课程
号。
SELECT Sno, Cno
FROM SC x
WHERE Grade >=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
- 带有ANY(SOME)或ALL谓词的子查询
谓词语义
➢ ANY:任意一个值
➢ ALL:所有值
.> ——ANY 大于子查询结果中的某个值
.> ——ALL 大于子查询结果中的所有值
.< ——ANY 小于子查询结果中的某个值
.< ——ALL小于子查询结果中的所有值
.>= ——ANY 大于等于子查询结果中的某个值
.>= ——ALL 大于等于子查询结果中的所有值
.<= ——ANY小于等于子查询结果中的某个值
.<= ——ALL 小于等于子查询结果中的所有值
.= ——ANY 等于子查询结果中的某个值
.= ——ALL等于子查询结果中的所有值(通常没有实际意义)
.!= ——(或<>)ANY 不等于子查询结果中的某个值
.!= ——(或<>)ALL 不等于子查询结果中的任何一个值
- 带有EXISTS谓词的子查询
- EXISTS谓词
1)存在量词∃
2)带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
➢若内层查询结果非空,则外层的WHERE子句返回真值
➢若内层查询结果为空,则外层的WHERE子句返回假值
3)由EXISTS引出的子查询,其目标列表达式通常都用* ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义 - NOT EXISTS谓词
➢若内层查询结果非空,则外层的WHERE子句返回假值
➢若内层查询结果为空,则外层的WHERE子句返回真值
四、 集合查询
1. 集合操作的种类
➢ 并操作UNION
➢ 交操作INTERSECT
➢ 差操作EXCEPT
2. 参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同
五、Select语句的一般形式
SELECT [ALL|DISTINCT]
<目标列表达式> [别名] [ ,<目标列表达式>
[别名]] …
FROM <表名或视图名> [别名]
[ ,<表名或视图名> [别名]] …
[WHERE <条件表达式>]
[GROUP BY <列名1>
[HAVING <条件表达式>]]
[ORDER BY <列名2> [ASC|DESC]
数据更新
一、插入数据
1. 两种插入数据方式
1)插入元组
INSERT
INTO <表名> [(<属性列1>[,<属性列2 >…)]
VALUES (<常量1> [,<常量2>] … )
- INTO子句
属性列的顺序可与表定义中的顺序不一致
没有指定属性列
指定部分属性列 - VALUES子句
提供的值必须与INTO子句匹配:
值的个数
值的类型
2)插入子查询结果
INSERT
INTO <表名> [(<属性列1> [,<属性列2>… )]
子查询;
- INTO子句
属性列的顺序可与表定义中的顺序不一致
没有指定属性列
指定部分属性列 - 子查询
SELECT子句目标列必须与INTO子句匹配:
值的个数
值的类型
RDBMS在执行插入语句时会检查所插元组是否破坏表上已定义的完整性规则:
➢ 实体完整性
➢ 参照完整性
➢ 用户定义的完整性:NOT NULL约束;UNIQUE约束;值域约束
二、修改数据
1. 语句格式
UPDATE <表名>
SET <列名>=<表达式>[,<列名>=<表达式>]…
[WHERE <条件>];
2. 功能
修改指定表中满足WHERE子句条件的元组
- SET子句
➢指定修改方式
➢要修改的列
➢修改后取值 - WHERE子句
➢指定要修改的元组
➢缺省表示要修改表中的所有元组
3. 三种修改方式
修改某一个元组的值
修改多个元组的值
带子查询的修改语句
RDBMS在执行修改语句时会检查修改操作是否破坏表上已定义的完整性规则:
➢实体完整性
➢主码不允许修改
➢用户定义的完整性: NOT NULL约束;UNIQUE约束;值域约束
三、删除数据
1. 语句格式
DELETE
FROM <表名>
[WHERE <条件>];
2. 功能
删除指定表中满足WHERE子句条件的元组
3. WHERE子句
指定要删除的元组
缺省表示要删除表中的全部元组,表的定义仍在字典中
4. 三种删除方式
删除某一个元组的值
删除多个元组的值
带子查询的删除语句
视图
视图的特点:
- 虚表,是从一个或几个基本表(或视图)导出的表
- 只存放视图的定义,不存放视图对应的数据
- 基表中的数据发生变化,从视图中查询出的数据也
随之改变
一、定义视图
1.建立视图
CREATE VIEW
<视图名> [(<列名> [,<列名>]…)]
AS <子查询> [WITH CHECK OPTION];
1)组成视图的属性列名:全部省略或全部指定
➢ 省略:由子查询中SELECT目标列中的诸字段组成
➢ 明确指定视图的所有列名:
(1) 某个目标列是集函数或列表达式
(2) 目标列为 *
(3) 多表连接时选出了几个同名列作为视图的字段
(4) 需要在视图中为某个列启用新的更合适的名字
2)子查询不允许含有ORDER BY子句和DISTINCT短语
RDBMS执行CREATE VIEW语句时只是把视图定义存入数据字典,并不执行其中的SELECT语句。
在对视图查询时,按视图的定义从基本表中将数据查出
2.删除视图
DROP VIEW <视图名>;
➢ 该语句从数据字典中删除指定的视图定义
➢ 如果该视图上还导出了其他视图,使用CASCADE级
联删除语句,把该视图和由它导出的所有视图一
起删除
➢ 删除基表时,由该基表导出的所有视图定义都必
须显式地使用DROP VIEW语句删除
二、查询视图
- 用户角度:查询视图与查询基本表相同
- RDBMS实现视图查询的方法
➢ 视图消解法(View Resolution)
• 进行有效性检查
• 转换成等价的对基本表的查询
• 执行修正后的查询
有些情况下,视图消解法不能生成正确查询。
三、更新视图
更新视图和更新基本表相同
更新视图的限制:一些视图是不可更新的,因为对这些
视图的更新不能唯一地有意义地转换成对相应基本表的
更新
实际系统对视图更新的限制
(1) 若视图是由两个以上基本表导出的,则此视图不允许更新。
(2) 若视图的字段来自字段表达式或常数,则不允许对此视图执行INSERT和UPDATE操作,但允许执行DELETE操作。
(3) 若视图的字段来自集函数,则此视图不允许更新。
(4) 若视图定义中含有GROUP BY子句,则此视图不允许新。
(5) 若视图定义中含有DISTINCT短语,则此视图不允许更新。
(6) 若视图定义中有嵌套查询,并且内层查询的FROM子句中涉及的表也是导出该视图的基本表,则此视图不允许更新。
(7) 一个不允许更新的视图上定义的视图也不允许更新
四、视图的作用
1.视图能够简化用户的操作
2. 视图使用户能以多种角度看待同一数据
3. 视图对重构数据库提供了一定程度的逻辑独立性
4. 视图能够对机密数据提供安全保护
5. 适当的利用视图可以更清晰的表达查询