第一章 绪论
数据(Data)是数据库中存储的基本对象,描述事物的符号记录
数据库(Database,简称 DB)是长期储存在计算机内、有组织的、可共享的大量数据集合
数据库管理系统(Database Management System,简称 DBMS)是位于用户与操作系统之
间的一层数据管理软件,用于科学地组织和存储数据、高效地获取和维护数据
DBMS 功能:
数据定义语言(DDL):定义数据库中的数据对象
数据操纵语言(DML):操纵数据实现对数据库的基本操作
数据库的运行管理
数据库的建立和维护功能
数据库系统(Database System,简称 DBS)是指在计算机系统中引入数据库后的系统构成,
由数据库、数据库管理系统(及其开发工具)、应用系统、数据库管理员(和用户)构成。
DBMS 对数据的控制功能:安全性(Security)保护、完整性(Integrity)检查、并发(Concurrency)
控制、数据库恢复(Recovery)
数据独立性
物理独立性指用户的应用程序与存储在磁盘上的数据库中数据是相互独立的。当数据的
物理存储改变了,应用程序不用改变。
逻辑独立性指用户的应用程序与数据库的逻辑结构是相互独立的。数据的逻辑结构改变
了,用户程序也可以不变
数据模型分成两层
(1) 概念模型,也称信息模型,它是按用户的观点来对数据和信息建模
概念模型是现实世界到机器世界的一个中间层次
(2) 数据模型,主要包括网状、层次、关系模型等,它是按计算机系统的观点对数据建模
客观对象的抽象过程---两步抽象
现实世界中的客观对象抽象为概念模型;
把概念模型转换为某一 DBMS 支持的数据模型
关系模型的完整性约束:实体完整性、参照完整性、用户定义的完整性
数据的独立性:高度的物理独立性和一定的逻辑独立性
数据库系统的模式结构
模式(也称逻辑模式):数据库中全体数据的逻辑结构和特征的描述,所有用户的公共数据
视图,综合了所有用户的需求。一个数据库只有一个模式,是数据库系统模式结构的中间层
外模式(也称子模式或用户模式):数据库用户(包括应用程序员和最终用户)使用的局部
数据的逻辑结构和特征的描述,数据库用户的数据视图,是与某一应用有关的数据逻辑表示
内模式(也称存储模式):是数据物理结构和存储方式的描述,是数据在数据库内部的表示
方式,一个数据库只有一个内模式
三级模式与二级映象
1.外模式/模式映象:保证数据的逻辑独立性,
2.模式/内模式映象:保证数据的物理独立性
第二章 关系数据库
关系的三类完整性约束:
1.实体完整性:主属性都不能取空值
2.参照完整性:外码或者取空值,或者或者等于 S 中某个元组的主码值
(外码:设 F 是基本关系 R 的一个或一组属性,但不是关系 R 的码。如果 F 与基本关系 S
的主码 Ks 相对应,则称 F 是基本关系 R 的外码)
3.用户定义的完整性:针对某一具体关系数据库的约束条件,反映某一具体应用所涉及的数
据必须满足的语义要求
实体完整性和参照完整性是关系模型必须满足的完整性约束条件,是关系的两个不变性
专门的关系运算
1.选择(Selection):在关系 R 中选择满足给定条件的诸元组 σF(R) = {t|tR∧F(t)= '真'}
F:选择条件,是一个逻辑表达式,
例:σSage < 20(Student) 查询年龄小于 20 岁的学生
2.投影(Projection):πA(R) = { t[A] | tR} A 是 R 中的属性列
例:πSdept(Student) 查询学生关系 Student 中都有哪些系
3.连接(Join):从两个关系的笛卡尔积中选取属性间满足一定条件的元组
RAθBS = {
tr ts
| t r R∧t s S∧t r[A]θt s[B] }
等值连接(equijoin):从关系 R 与 S 的广义笛卡尔积中选取 A、B 属性值相等的那些元组
自然连接(Natural join):两个关系中进行比较的分量必须是相同的属性组,在结果中把重
复的属性列去掉
4.除(Division):给定关系 R (X,Y) 和 S (Y,Z),其中 X,Y,Z 为属性组。R 中的 Y 与 S
中的 Y 可以有不同的属性名,但必须出自相同的域集,元组在 X 上分量值 x 的象集 Yx 包含
S 在 Y 上投影的集合。
R÷S = {tr [X] | tr R∧πY (S) Yx }
象集:R 中属性组 X 上值为 x 的诸元组在 Z 上分量的集合
Yx:x 在 R 中的象集,x = tr[X]
综合示例:
(1)查询选修了 2 号课程的学生的学号 πSno(σCno='2'(SC))={ 95001,95002}
(2)查询至少选修了一门其直接先行课为 5 号课程的课程的学生姓名
πSname(σCpno='5'(Course*SC*Student)) (用*代替连接号)
(3)查询选修了全部课程的学生号码和姓名
πSno,Cno(SC)÷πCno(Course)*πSno,Sname(Student)
第三章 关系数据库标准语言 SQL
数据定义语言 DDL:CREATE, ALTER, DROP
数据操纵语言 DML:INSERT, UPDATE, DELETE
数据控制语言 DCL:GRANT, REVOKE
【数据定义】
1. 定义基本表
CREATE TABLE <表名>
(<列名> <数据类型>[ <完整性约束条件> ],。。。);
常用完整性约束:
主码约束: PRIMARY KEY
唯一性约束:UNIQUE
非空值约束:NOT NULL
示例:CREATE TABLE Student
CHAR(5) NOT NULL UNIQUE,
(Sno
Sname CHAR(20) UNIQUE,
Ssex
Sage
Sdept
CHAR(1) ,
INT,
CHAR(15));
2. 修改基本表
ALTER TABLE <表名>
[ ADD <新列名> <数据类型> [ 完整性约束 ] ]
[ DROP <完整性约束名> ]
[ MODIFY <列名> <数据类型> ];
示例:ALTER TABLE Student ADD Scome DATE;
ALTER TABLE Student MODIFY Sage SMALLINT;
ALTER TABLE Student DROP UNIQUE(Sname);
3. 删除基本表
DROP TABLE <表名>;
数据、表上的索引都删除,表上的视图往往仍然保留,但无法引用
直接删除属性列(新) 例:ALTER TABLE Student Drop Scome;
示例:DROP TABLE Student;
4. 建立索引
CREATE [UNIQUE] [CLUSTER] INDEX <索引名> ON <表名>(<列名>[<次序>][,<列名>[<
次序>] ]…);
索引可以建立在该表的一列或多列上,各列名之间用逗号分隔
用<次序>指定索引值的排列次序,升序:ASC,降序:DESC。缺省值:ASC
UNIQUE:此索引的每一个索引值只对应唯一的数据记录
CLUSTER:要建立的索引是聚簇索引
注:聚簇索引的索引项顺序与表中记录的物理顺序一致
在一个基本表上最多只能建立一个聚簇索引
适用范围:很少对基表进行增删操作,很少对其中的变长列进行修改操作
示例:CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC);
5. 删除索引
DROP INDEX <索引名>;
示例:DROP INDEX Stusname;
【查询】
1. 单表查询
SELECT [ALL(默认)|DISTINCT] <目标列表达式>
[,<目标列表达式>] …
FROM <表名或视图名>[, <表名或视图名> ] …
[ WHERE <条件表达式> ]
[ GROUP BY <列名 1> [ HAVING <条件表达式> ] ]
[ ORDER BY <列名 2> [ ASC(默认)|DESC ] ];
GROUP BY 子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常
会在每组中作用集函数。
HAVING 短语:筛选出只有满足指定条件的组
(1) SELECT 子句的<目标列表达式>为表达式、算术表达式、字符串常量、函数、列别名等
示例:查询全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名
SELECT Sname,’Year of Birth:’ BIRTH ,2000-Sage,ISLOWER(Sdept)
FROM Student;
输出结果:
Sname
-------
李勇 Year of Birth:
----------------
BIRTH
2000-Sage
--------- -
1976
ISLOWER(Sdept)
-------------
cs
(2) DISTINCT 短语的作用范围是所有目标列
示例:查询选修课程的各种成绩 SELECT DISTINCT Cno,Grade FROM SC;
(3) WHERE 子句常用的查询条件
<比较条件> =,>,<,>=,<=,!= 或 <>,!>,!<,
逻辑运算符 NOT + 比较运算符
示例:查询所有年龄在 20 岁以下的学生姓名及其年龄
SELECT Sname,Sage
FROM
WHERE Sage < 20; 或 NOT Sage >= 20;
Student
<确定范围> BETWEEN … AND …
NOT BETWEEN … AND …
示例:查询年龄不在 20~23 岁之间的学生姓名、系别和年龄
SELECT Sname,Sdept,Sage
FROM
WHERE Sage NOT BETWEEN 20 AND 23;
Student
<确定集合> IN <值表>, NOT IN <值表>(<值表>:用逗号分隔的一组取值)
示例:查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。
SELECT Sname,Ssex
FROM Student
WHERE Sdept IN ( 'IS','MA','CS' );
<字符串匹配> [NOT] LIKE ‘<匹配串>’
[ESCAPE ‘ <换码字符>’]
当匹配模板为固定字符串时,可以用 = 运算符取代 LIKE 谓词
用 != 或 < >运算符取代 NOT LIKE 谓词
% (百分号) 代表任意长度(长度可以为 0)的字符串
_ (下横线) 代表任意单个字符
当用户要查询的字符串本身就含有 % 或 _ 时,要使用 ESCAPE '<换码字符
>' 短语对通配符进行转义
示例:查询以"DB_"开头,且倒数第 3 个字符为 i 的课程的详细情况。
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i_ _' ESCAPE ' \ ';
<空值的查询> IS NULL 或 IS NOT NULL(”IS NULL”不能用“= NULL”代替)
示例:查所有有成绩的学生学号和课程号。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;
<多重条件查询> 用逻辑运算符 AND 和 OR 来联结多个查询条件
AND 的优先级高于 OR,可以用括号改变优先级
示例:查询计算机系年龄在 20 岁以下的学生姓名
SELECT Sname
FROM Student
WHERE Sdept= 'CS' AND Sage<20;
(4) 排序:使用 ORDER BY 子句,升序:ASC;降序:DESC;缺省值为升序
ASC:排序列为空值的元组最后显示,DESC:排序列为空值的元组最先显示
示例:查询全体学生情况,结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
SELECT *
FROM Student
ORDER BY Sdept,Sage DESC
(5) 集函数
计数: COUNT([DISTINCT|ALL] *)
COUNT([DISTINCT|ALL] <列名>)
计算总和:SUM([DISTINCT|ALL] <列名>)
计算平均值:AVG([DISTINCT|ALL] <列名>)
求最大值:MAX([DISTINCT|ALL] <列名>)
求最小值:MIN([DISTINCT|ALL] <列名>)
DISTINCT 短语:在计算时要取消指定列中的重复值;ALL 短语:不取消重复值,为缺省值
示例:查询选修了课程的学生人数
SELECT COUNT(DISTINCT Sno)
FROM SC;
示例:计算 1 号课程的学生平均成绩。
SELECT AVG(Grade)
FROM SC
WHERE Cno= ' 1 ';
(6) 分组:使用 GROUP BY 子句分组方法:按指定的一列或多列值分组,值相等的为一组;
使用 GROUP BY 子句后,SELECT 子句的列名列表中只能出现分组属性和集函数;
示例:求各个课程号及相应的选课人数
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
示例:查询有 3 门以上课程是 90 分以上的学生的学号及(90 分以上的)课程数
SELECT Sno, COUNT(*)
FROM SC
WHERE Grade>=90
GROUP BY Sno
HAVING COUNT(*)>=3;
使用 HAVING 短语筛选,只有满足 HAVING 短语指定条件的组才输出
HAVING 短语与 WHERE 子句区别:作用对象不同
WHERE 子句作用于基表或视图,从中选择满足条件的元组。
HAVING 短语作用于组,从中选择满足条件的组。
2.连接查询
同时涉及多个表的查询。连接条件中的各连接字段类型必须是可比的,但不必是相同的。
一般格式:[<表名 1>.]<列名 1> <比较运算符> [<表名 2>.]<列名 2>
比较运算符:=、>、<、>=、<=、!=
[<表名 1>.]<列名 1> BETWEEN [<表名 2>.]<列名 2> AND [<表名 2>.]<列名 3>
(1) 等值与非等值连接查询
等值连接:[<表名 1>.]<列名 1> = [<表名 2>.]<列名 2>
自然连接:等值连接的一种特殊情况,把目标列中重复的属性列去掉,即指明列所属表
非等值连接查询:>、<、>=、<=、!=
(2) 自身连接
需要给表起别名以示区别
示例:查询每一门课的间接先修课(即先修课的先修课)
BETWEEN …AND…
SELECT FIRST.Cno,SECOND.Cpno
FROM Course FIRST,Course SECOND
WHERE FIRST.Cpno = SECOND.Cno;
(3) 外连接
以指定表为连接主体,将主体表中不满足连接条件的元组一并输出;
在表名后面加外连接操作符(*)或(+)指定非主体表,非主体表有一“万能”的虚行,该行全
部由空值组成,虚行可以和主体表中所有不满足连接条件的元组进行连接
查询每个学生及其选修课程的情况包括没有选修课程的学生----用外连接操作
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM
WHERE Student.Sno = SC.Sno(*);
Student,SC
(4) 复合条件连接
WHERE 子句中含多个连接条件
示例:查询选修 2 号课程且成绩在 90 分以上的所有学生的学号、姓名
SELECT Student.Sno, student.Sname
FROM Student, SC
WHERE Student.Sno = SC.Sno AND SC.Cno= ' 2 ' AND SC.Grade > 90;
3.嵌套查询
一个 SELECT-FROM-WHERE 语句称为一个查询块,将一个查询块嵌套在另一个查询块的
WHERE 子句或 HAVING 短语的条件中的查询称为嵌套查询。
子查询的限制:不能使用 ORDER BY 子句
求解方法:
不相关子查询:是由里向外逐层处理。即每个子查询在上一级查询处理之前求解,子查
询的结果用于建立其父查询的查找条件;
相关子查询:首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理
内层查询,若 WHERE 子句返回值为真,则取此元组放入结果表;然后再取外层表的下一个
元组;重复这一过程,直至外层表全部检查完为止。
(1) 带有 IN 谓词的子查询
示例:查询与“刘晨”在同一个系学习的学生。
嵌套查询:
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept
IN
(SELECT Sdept
FROM Student
WHERE Sname= ‘ 刘晨 ’);
自身连接查询:
SELECT S1.Sno,S1.Sname,S1.Sdept
FROM
WHERE S1.Sdept = S2.Sdept AND S2.Sname = '刘晨';
Student S1,Student S2
(2) 带有比较运算符的子查询
当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或< >),与
ANY 或 ALL 谓词配合使用
子查询一定要跟在比较符之后
示例:假设一个学生只可能在一个系学习,并且必须属于一个系,则上例可以用=代替 IN :
SELECT Sno,Sname,Sdept
FROM
WHERE Sdept
Student
=
SELECT Sdept
FROM Student
WHERE Sname= ' 刘晨 ';
(3) 带有 ANY 或 ALL 谓词的子查询
ANY:任意一个值,某个值
ALL:所有值
示例:查询其他系中比信息系任意一个(其中某一个)学生年龄小的学生姓名和年龄
SELECT Sname,Sage
FROM Student
WHERE Sage < ANY (SELECT Sage
FROM Student
WHERE Sdept= ' IS ')
AND Sdept <> ' IS ' ;
ANY 和 ALL 谓词有时可以用集函数实现,用集函数实现子查询通常比直接用 ANY 或 ALL
查询效率要高,因为前者通常能够减少比较次数
示例:查询其他系中比信息系任意一个(其中某一个)学生年龄小的学生姓名和年龄
SELECT Sname,Sage
FROM Student
WHERE Sage <
(SELECT MAX(Sage)
FROM Student