数据库
这里主要是复习的时候听着网课重新做一遍笔记。
# 一,绪论
# 介绍
# 数据库系统概述
# 数据
数据是数据库中存储的基本对象。
[定义] 计算机用来描述事物的符号记录(文字.图形.图像.声音)
- 数据的形式本身并不能完全表达其内容,需要经过语义解释。特点:数据与其语义是不可分的
# 数据库 DB
- 数据库是长期存储在计算机内有结构的大量的共享的数据集合。(有组织,可共享)
# 数据库管理系统 DBMS
[定义] 数据库管理系统是位于用户与操作系统之间的一层数据管理软件。
主要功能:
- 数据定义功能
- 数据组织,存储和管理功能
- 数据操纵功能(插入,查询,删除,修改等)
- 数据库的事务管理和运行管理(安全性,完整性,多用户并发处理)
- 数据库的建立和维护功能
# 数据库系统 DBS
[定义] 数据库系统由数据库(DB),数据库管理系统(DBMS),应用系统,数据库管理员(DBA)构成。
# 数据管理技术的发展
一,人工管理阶段
- 数据不保存
- 数据不共享
- 应用程序管理数据
- 数据不独立
二,文件系统阶段 - 数据保存
- 文件系统管理数据
- 数据共享差,冗余大
- 数据独立性差
三,数据库系统阶段 - 数据结构化
- 数据共享性高,冗余度低,易扩充
- 数据独立性高
- 数据由 DBMS 同一管理和控制:安全,完整,并发,恢复
# 数据模型
[定义] 一组概念的集合,对现实世界数据特征进行抽象。
- 概念模型 : 按照用户观点建模,用于数据库设计
- 逻辑和物理模型
逻辑模型:按计算机系统观点对数据建模, 用于 DBMS 的实现。主要包括:层次模型,网状模型,关系模型(二维表的数据库),面向对象模型和对象关系模型。
物理模型:系统内部或磁盘上表示方式、存取方法,面向计算机系统。其是对数据最底层的抽象
# 数据模型的组成元素
一,数据结构
描述数据库的组成对象,以及对象之间的联系。数据结构是所描述的对象类型的集合,是对系统静态特性的描述。
二,数据操作
数据库主要有查询和更新(包括插入,删除,修改等),两大类操作。是对系统动态特性的描述。
三,数据的完整性约束条件
数据的完整性约束条件是一组完整性规则。
【例】 关系模型中,任何的关系必须满足实体完整性和参照完整性。
# 概念模型
定义:
- 概念模型用于信息世界的建模
- 现实世界到信息世界的第一层抽象
- 数据库设计人员进行数据库设计的有力工具
- 数据库设计人员和用户之间进行交流的语言
概念模型要求: - 具有较强的语义表达能力
- 能够方便,直接的表达应用中的各种语义知识
- 简单,清晰,易于用户理解
一,信息世界中的基本概念
1,实体 Entity
客观存在并且可以相互去别的事务即实体。可以是人,事,物,也可以是抽象的概念或者联系。
【例】 一个职工,学生,部门,课等都是实体
2,属性
实体所具有的某一特性称为属性。一个实体可以由若干个属性来刻画。
【例】学生的 学号,姓名 等
3,码 key
唯一标识实体的属性集称为码。
4,域
具有相同数据类型的值的集合。即属性的取值范围。
5,实体型
具有相同属性的实体必然具有共同的特征和性质。
6,实体集
同一类型实体的集合称为实体集。
7,联系
现实世界中,事务内部以及事物之间是有联系的。实体内部各个属性的联系或者不同实体集之间的联系。
二,两个实体型之间的联系
1,一对一
对于 A 中的每一个实体,B 中至多有一个(可以没有)实体与之联系,反之亦然。
【例】一个班级只有一个班长
2,一对多
A 中的一个实体,B 中有 n 个实体与之联系,但是 B 中每一个实体在 A 中最多只有一个实体联系。
【例】一个班级有若干名学生,学生只能在一个班级学习。
3,多对多
A 中的每一个实体,B 中有多个,反之也是一样。
三,概念模型得表示方法:实体 - 联系方法
实体联系方法用 E-R 图来描述现实世界得概念模型,所刻画的某些也称为 E-R 模型。
# 数据模型得组成要素
- 数据结构:数据结构是所研究得对象类型得集合
- 数据操作:对数据库得对象(型)的实例(值)进行操作(查询,更新)
- 数据的完整性约束条件:实体完整性,参照完整性。满足条件来保证数据的正确性,有效性和相容性
# 数据库系统结构
# 从最终用户角度看
- 单用户结构:最简单的数据库系统,整个 DBS 都装在一个计算机上,由一个用户独占
- 主从式结构:一个主机带多个终端的多用户结构。DBS 集中存放在主机上,所有处理任务都由主机来完成,用户通过主机的终端并发存取数据库,共享数据资源。
- 分布式结构:一个应用程序可以对数据库进行透明操作,数据库中的数据分别存储在不同的局部数据库中,由不同的 DBMS 进行管理,在不同的机器上允许,由不同的操作系统支持,被不同的通信网络连接在一起。
- 客户 - 服务器结构:服务器负责数据的管理,客户机负责完成与用户的交互任务。
# 数据库系统模式概念
(1)型和值
- 型 (type):对某一类数据的结构和属性的说明
- 值 (value):是型的一个具体赋值
(2)模式和实例
模式 (schema):是数据库逻辑结构和特征的描述 - 是型的描述
- 反应的是数据的结构及其联系
- 模式相对稳定
实例 (instance):模式的一个具体值 - 反映数据库某一时刻的状态
- 同一个模式可以有很多实例
- 实例随数据中的数据的更新而变动
(3)三级模式 - 模式:是数据库中全体数据的逻辑结构和特征得描述,同一个模式可以有多个实例。一个数据库只有一个模式。
- 外模式:数据库用户能看见和使用得局部数据得逻辑结构和特征得描述,是数据库用户得数据视图,与某一应用有关的数据的逻辑表示。外模式通常是模式的一个子集,所以模式与外模式的关系为一对多。
- 内模式:也称存储模式,是数据物理结构和存储方式的描述,是数据在数据库内部的组织方式。
(4)二级映像
模式 / 内模式有映像:保证数据与程序的物理独立性。当数据库的存储结构改变时 (例如选用了另一种存储结构),由数据库管理员对模式 / 内模式映像作相应改变,可以使模式保持不变。从而应用程序不必改变,保证了数据与程序的物理独立性,简称数据的物理独立性。
外模式 / 模式有映像:定义全局逻辑结构和存储结构之间的对应关系,保证数据和程序的逻辑独立性。当模式改变时 (例如增加新的关系、新的属性、改变属性的数据类型等),由数据库管理员对各个外模式 / 模式的映像作相应改变,可以使外模式保持不变。应用程序是依据数据的外模式编写的,从而应用程序不必修改,保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。
# 数据库技术的研究领域和发展趋势
数据库技术和相关技术的相结合
- 分布式数据库系统:数据库技术 + 分布式处理技术
- 并行数据库系统:数据库技术 + 并行处理技术
- 多媒体数据库系统:数据库技术 + 多媒体处理技术
- 移动数据库系统:数据库技术 + 移动通信技术
- Web 数据库系统:数据库技术 + Web 技术
- 自主数据库系统:数据库技术 + 人工智能技术
# 二,关系数据库
# 关系
单一的数据结构 — 关系
逻辑结构 — 二维表
关系模型是建立在集合代数的基础上的
关系模型是用关系表示实体及其联系
关系 -> 二维表
# 概念
1,域
具有相同数据类型的值的集合。即属性的取值范围。
2,笛卡尔积
给定一组域 , , , , 这些域的笛卡尔积为 × ×…× =($d_1$,$d_2$,…,$d_n$)|$d_i$∈$D_i$,i=1,2,3,…,n}
**3, 元组 **
笛卡尔积中每一个元素乘坐一个 n 元组。表的每一行叫做一个元组。
**4,分量 **
元素中每一个值 $d_i$ 称做一个分量。
**5,基数 **
若 $D_i$ 为有限集,其基数为 $m_i$,则 $D_1$ × $D_2$ … $D_n$ 的基数为 M = $\prod_{i=1}$$m_i$
# 码
- 候选码:若关系中的某一属性组能唯一标识一个元组,而其子集不能,则称该属性组为候选码。
- 全码(ALL-key):最极端的情况,关系模式的所有属性共同构成这个关系模式的候选码,称为全码。
- 主码:若一个关系有多个候选码,则选定一个作为主码(Primary key)。能够唯一标识一条记录的最小属性集。
- 主属性:候选码的诸个属性称为主属性
- 非主属性:不包含在任何候选码中的属性 (或者说非码属性)。
# 三类关系
- 基本关系 (基本表):实际存在的表,是实际存储数据的逻辑表示
- 查询表:查询结果对应的表
- 视图表:有基本表或者其他视图表导出的表,是虚表,不对应实际存储的数据。
# 关系模式
【定义】 是对关系的描述。关系模式是型,关系是值。 关系模式是静态的。
关系的形式化表示:R (U, D, dom, F)
R:关系名 U:组成该关系的属性集合 DOM:属性项域的映像集合 F:属性间的数据依赖关系集合
# 关系数据库
一个给定的应用领域中,所有关系的集合构成一个关系数据库。
# 关系的完整性
【定义】: 关系模型中有三类完整性约束:实体完整性,参照完整性,用户定义的完整性。
注意: 为保证数据库中数据的正确性,通常定义完整性约束的方式是:存储过程,Check 约束,On Delete no Action。
# 实体完整性
是指若属性 A 是基本关系 R 的主属性,则 A 不能取空值。
实体完整性规则的说明:
(1)主码不能为空值。(所有的主属性都不能取空值)
(2)两个元素的主码不能相同。
# 参照完整性
这里介绍一下外码 / 外键。
定义:设 F 是基本关系 R 的一个或一组属性,但不是关系 R 的码。如果 F 与基本关系 S 的主码 相对应,则称 F 是基本关系 S 的外码。 基本关系 R 为参照关系,基本关系 S 为被参照关系。
参照完整性规则:
对于 R 上每个元组在 F 上的取值:要么取空值,要么等于 S 中某个元组的主码值。
例如有如下两个关系:
- 部门 (部门号,部门名,电话)
- 雇员 (雇员号,雇员名,职称,)
这里得部门号即外码,可以取部门中部门号得取值或者空值。
值得注意的是,外键可能来自同一关系,也就是被参照关系就是参照关系。
Students(sid, name, login, age, gpa, ), partner 是 对 sid 的一个外键约束,一个学生可能没有同伴,故其可以取空,相应的,对于课程,当一门课程没有前期课程时,preq 可以为空,空值并不违反外键约束
# 用户定义的完整性
这里就是自己对数据加上域,即添加约束。用户自定义完整性 1 针对某一具体关系数据库的约束条件,反映某一具体应用所涉及的数据必须满足的语义要求,例如某个属性必须取唯一值,某个非主属性不能取空值等等.
# 关系代数
# 传统的集合运算
注意这里默认 R 和 S 都有相同的目 n(都具有 n 个属性)
1,并 (union)
R 并 S,即在 R 也在 S 的元素集合
2,差 (expect)
R 差 S,在 R 中而不在 S 中的元素的集合
3,交 (intersection)
R 交 S,既属于 R 又属于 S 的元组组成。
4,笛卡尔积
R:n 目,k 个元组 S:m 目,t 个元组
R X S :结果 行: k × t 个元组 列: (n+m) 个列
# 专门的关系运算
1,选择
通过条件筛选来查询相应数据。例如(student) 表示查询年龄小于 20 的学生。
2,投影运算
只从关系 R 中选取若干属性组成新的关系。例如,是只查询学生的姓名和所在系。
3,连接运算
R 和 S 进行连接运算的结果:从 R 和 S 的广义笛卡尔积 R × S 中选取 (R 关系) 在 A 属性组上的值与(S 关系)在 B 属性组上值满足关系 θ 的元组。
- 等值连接:从关系 R 和 S 的广义笛卡尔积中找到 A 和 B 属性相等的那些元组。(A 和 B 可以不是同一个属性)。这里没有去掉重复列。
- 自然连接:是一种特殊的等值连接,R 和 S 中具有相同属性组 B,在结果结果中把重复的属性列去掉。
- 外连接:悬浮元组的概念:R 和 S 在做自然连接时,R 中某些元组有可能在 S 中不存在公共属性上值相等的元组,就会造成 R 中这些元组在操作时被舍弃(反过来 S 也是这样)。
4,除运算
这里先给出象集的定义:当在 R 关系中属性 A 取 x 值时,其他属性例如 B 可以取什么值,这个取得值得集合称为 1 象集。
R÷S={tr [X]| tr∈R 并且(S) Yx}
那么 R 除 S,假设 R 中 得 B,C 属性 是 R 和 S 共同属性,那么就找 R 中哪个 A 得元素得象集能包含 S 中所有得 B,C 得取值得。
# 三,关系数据库标准语言 SQL
语法说明:
<>:尖括号用于分隔字符串
[]:方括号表示规则中的可选元素,可以选择也可以省略
{}:花括号表示聚集规则中的元素,必须明确指定
# 1,模式得定义和删除
1,定义模式:CREATE SCHEMA <模式名> AUTHORIZATION < 用户名 >; 若没有指定模式名 则默认为用户名。
2,删除模式:DROP SCHEMA <模式名> <CASCADE|RESTRICT>;
①CASCADE 和 RESTRICT 必须二选一。
②CASCADE (级联删除)
③RESTRICT (限制删除)
# 2,基本表的定义,删除和修改
1, 创建基本表
CREATE TABLE <表名> (< 列名 >< 数据类型 >[< 列级完整性约束条件 >][,< 列名 >< 数据类型 >[< 列级完整性约束条件 >]]…[,< 表级完整性约束条件 >]);
- 如果完整性约束条件涉及该表的多个属性列,则必须定义在表级上,否则既可以在列级上也可以在表级上
【例 3】:建立学生选课表SC
,其中Sno
和Cno
是外码,分别参照Student
表的Sno
列和Course
表的Cno
列 Sno
和Cno
是SC
的主码,必须使用表级完整性定义
1 | CREATE TABLE SC |
2,修改基本表
-
ADD
:用于增加新列,新的列级完整性约束条件和新的表级完整性约束条件 -
DROP COLUMN
:用于删除表中的列 -
DROP CONSTRAINT
:用于删除指定的完整性约束条件 -
ALTER COLUMN
:用于修改原有的列定义
(3)删除基本表
- 选择
RESTRICT
:欲删除的基本表不能被其他表的约束所引用(比如 CHECK、FOREIGN KEY 等)、不能有视图、不能有触发器(trigger),不能有存储过程或函数等 - 选择
CASCADE
:没有限制条件,所有相关依赖对象连同基本表一起删除
3,创建索引
作用:建立索引是加快查询速度的有效手段 : 数据库索引类似于图书后面的索引,能快速定位需要查询的内容。下面是索引的类型: - 顺序文件上的索引
- B + 树索引
- 散列索引
- 位图索引
(1)建立索引
- <表名>:要建立索引的基本表的名字
- 索引可以建立在该表的一列或多列上,各列之间使用逗号分隔
- 每个 <列名> 后面还可以用 < 次序 > 指定索引值的排列次序,可选 ASC - 升序(默认)或 DESC - 降序
- UNIQUE:表明此索引的每一个索引值只对应唯一的数据记录
- CLUSTER:表示需要建立聚簇索引 - 一个基本表只能有一个聚簇索引,最快的,但应该在查询多而修改少的表中建立(第七章会讲到)
(2)修改索引
ALTER INDEX <旧索引名> RENAME TO < 新索引名 >;
(3)删除索引
DROP INDEX <索引名>;
# 附加:数据字典
这里提一下一个概念,数据字典。
- 关系数据库管理系统内部的一组系统表。
- 记录了数据库所有的表定义信息,包括模式定义,视图定义,索引定义,完整性约束定义,各类用户对数据库的操作权限,统计信息等。
- RDBMS 执行 SQL 数据定义时,实际上就是更新数据字典。****
# 基本表的查询
SELECT 语句含义:根据 WHERE 子句的条件表达式从 FROM 子句指定的表、视图中找出满足条件的元组,再按照 SELECT 子句中的目标列表达式选出元组中的属性值形成结果表。如果有:
- GROUP BY:结果按 <列名 1> 的值进行分组,该属性列值相等的元组为一个组;通常会在每组中作用聚集函数;如果该子句还携带 HAVING 短语,则只有满足指定条件的组才予以输出
- ORDER BY:结果表还要按 <列名 2> 的值的升序或降序排序
# 一,单表查询
(1)查询若干列
A:查询指定列
1 | SELECT Sname,Sage from Student; |
B:查询全部列 使用 * 来查询全部列
C:查询经过计算的值 可以利用算术表达式
(2)查询若干行
A:消除取值重复的行(DISTINCT)
语法:前面说过投影操作可能会导致相同的行出现所以其结果必须消除重复行。可以使用 DISTINCT
消除
1 | SELECT DISTINCT Sno from SC; |
B:查询满足条件的元组
通过 WHERE 语句实现,常见的查询条件如下:
这里用 like 进行字符匹配时有两个通配符
%: 任意长度的字符串。例如: A% b ----------- acb,addgb,ab,…
_ :任意单个字符。例如 a_b ----------- acb,adb,…
这里还要注意一下转义字符: \
这个字符用来转移_ 和 % 例如查询 DB_DESIGN,查询时需要用 LIKE 'DB\_DESIGN'
防止_自动识别任意字符。
(3)ORDER BY 语句
语法:ORDER BY 子句对查询结果按照一个或多个属性列进行排序
- ASC - 升序(默认)
- DESC - 降序
这里给一个例子:查询选修了 3 号课程的学生的学号及其成绩,查询结果按分数降序排列
1 | SELECT Sno,Grade |
(4)聚集函数
这里只给出一个例子:查询选修 2 号课程的学生最高分数
1 | SELECT Sno,MAX(Grade) |
(5)GROUP BY 子句
语法:GROUP BY 子句将查询结果按某一列或多列的值分组,值相等的分为一组
- 分组目的是为了细化聚集函数的作用对象:若未分组,聚集函数将会作用于整个查询结果;若分组,聚集函数将会作用于每一个组,也即每一个组都有一个函数值
- 需要注意:WHERE 子句作用于整个表或视图,从中选择出满足条件的元组;HAVING 短语作用于组,从中选择满足条件的组
这里举出一个例子说明GROUP BY
的作用,如果我查询各个课程的选修人数,则我需要按照课程号先对每个课程进行分组,再在每一组查询 Sno。
1 | SELECT Cno,Count(Sno) |
如果我只想显示那些选修人数大于 1 以上的课程,则可以用 HAVING
语句,在组内进行筛选
1 | SELECT Cno,Count(Sno) |
# 二,连接查询(查询时涉及多张表)
(1) 等值连接和非等值连接
语法:在 WHERE 子句中写入连接条件(又叫做连接每谓词),其格式为
其中比较运算符有: =
、 >
、 <
、 >=
、 <=
、 !=
- 当运算符为
=
时称之为等值连接 - 当运算符不为
=
时称之为非等值连接
例子:查询每个学生及其选修课程的情况
1 | SELECT student.*,sc.* |
例子:使用自然连接(即去掉重复列)
1 | SELECT student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade |
(2) 自身连接
语法:所谓自身连接就是指一个表与自己连接
例子:查询每一门课的先修课的先修课
- 在
Course
表中有的只是每门课的直接先修课,要想得到先修课的先修课,那么就必须先找到一门课的先修课,然后再按此先修课的课程号查找它的先修课
1 | SELECT ONE.Cno,TWO.Cpno |
(3) 连接 JOIN
语法:SQL JOIN 用于把来自两个或多个表的行结合起来,其格式如下
1 | SELECT column_name(s) |
有如下几类: 这里以查询学校内学生及雇员的情况。
INNER JOIN
(JOIN
) 既是学生,又是雇员。LEFT JOIN
(LEFT OUTER JOIN
) 是学生,可以不是雇员。RIGHT JOIN
(RIGHT OUTER JOIN
) 可以不是学生,但,是雇员FULL JOIN
(FULL OUTER JOIN
) 可以不是学生,可以不是雇员。
A:INNER JOIN(JOIN)
INNER JOIN
(JOIN
):关键字在表中存在至少一个匹配时返回行
以sc
和course
的Cno
作为比对标准,将相同连接在一起
1 | SELECT Sno,sc.Cno,Grade,course.Cno,Cname,Cpno,Ccredit |
B:LEFT JOIN (LEFT OUTER JOIN)
LEFT JOIN
( LEFT OUTER JOIN
):以左表为标准,若右表中无匹配,则填 NULL
1 | SELECT Sno,sc.Cno,Grade,course.Cno,Cname,Cpno,Ccredit |
C:RIGHT JOIN (RIGHT OUTER JOIN)
RIGHT JOIN
( RIGHT OUTER JOIN
):以右表为标准,若左表中无匹配,则填 NULL
1 | SELECT Sno,sc.Cno,Grade,course.Cno,Cname,Cpno,Ccredit |
D:FULL JOIN (FULL OUTER JOIN)
FULL JOIN
( FULL OUTER JOIN
):本质就是结合了 LEFT JOIN 和 RIGHT JOIN
1 | SELECT Sno,sc.Cno,Grade,course.Cno,Cname,Cpno,Ccredit |
(4) 符合条件连接
语法:没有什么新的东西,就是涉及多张表,多个条件的查询
(5) 集合操作的多关系查询
集合操作主要有 union,intersect 和 except
且集合操作一般可以利用多条条件语句代替
A,UNION
查询计算机系的学生以及年龄不大于 19 岁的学生
1 | select * |
B, INTERSECT
查询计算机系的学生与年龄不大于 19 岁的学生的交集
1 | select * |
C, EXCEPT
查询计算机系的学生与年龄不大于 19 岁的学生的差集
1 | select * |
# 三,嵌套查询
在 SQL 中,一个 SELECT-FROM-WHERE
语句称为一个查询块,将一个查询块嵌套在另一个查询块的 WHERE 子句或 HAVING 短语的条件中的查询称之为嵌套查询。比如: 内层循环查出来的是符合 Cno=2
的 Sno
集合,外层循环则在该集合内查询是否有满足的 Sno
,有的话显示 Sname
即可
1 | SELECT Sname //外层查询 |
需要注意下面几点:
- 子查询的 SELECT 语句不能使用
ORDER BY
子句 - 嵌套查询往往可以转换为对应的连接运算
嵌套查询分为不相关子查询和相关子查询。 - 不相关子查询:求解方法由里向外
- 相关子查询:求解方法由外向里
(1) 带有 IN 谓词的子查询
语法:嵌套查询中,子查询的结果往往是一个集合,所以 IN 在嵌套查询中使用次数最为频繁
例子:查询与 “刘晨” 在同一个系学习的学生 - 考虑时可以由内向外,先查询出刘晨所在的系,然后在该集合中查询满足该集合的学生姓名
1 | SELECT student.Sno,Sname,Sdept FROM student WHERE Sdept IN |
当然嵌套查询也可以转为连接完成:
1 | SELECT S1.Sno,S1.Sname,S1.Sdept |
(2) 带有比较运算符的子查询
语法:带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户能确切知道内层查询返回的是单个值时,可以使用 >
、 <
、 =
、 >=
、 <=
、 !=
等比较运算符
例子:查询与 “刘晨” 在同一个系学习的学生
1 | SELECT Sno,Sname,Sdept FROM student WHERE Sdept |
(3)带有 ANY(SOME)或 ALL 谓词的子查询
语法:内层查询返回单个值时使用比较运算符。如果返回多个值要用 ANY
(有的是 SOME)或 ALL
,然后同时使用比较运算符
例子:查询其他系比计算机科学系任意一个学生年龄小的学生姓名和年龄
1 | SELECT Sname,Sage FROM student WHERE Sage < ANY |
(4)带有 EXISTS 谓词的子查询
语法:EXISTS 代表存在量词,其不返回任何数据,只返回 TRUE
或者 FALSE
。另外,由 EXISTS 引出的子查询,其目标列表达式都是 *,因为列名没有意义。(写啥都行 1 也行)
- 若内层查询结果非空,则外层 WHERE 子句返回
true
- 若内层查询结果为空,则外层 WHERE 子句返回
false
与之相反的有NOT EXISTS
。
需要注意的是,一些带有 EXISTS 和 NOT EXISTS 谓词的子查询不能被其他形式的子查询等价替换;但是所有带 IN 谓词,比较运算符,ANY 和 ALL 谓词的子查询都可以用带 EXISTS 谓词的子查询替换
例子:查询所有选修了 1 号课程的学生姓名 - 处理时,首先会取外层查询中
Student
表的第一个元组,根据它与内层查询相关的属性值(Sno
)处理内层查询,若WHERE
子句返回为true
则取外层查询中该元组的Sname
放入结果表
1 | SELECT Sname FROM student WHERE |
例子 2:查询一个学生选修了所有的课程
着等价于:查询这样一个学生,没有一门课它是不选的
1 | SELECT Sname FROM Student WHERE NOT EXISTS( |
# 数据更新
# 一,插入数据
语法:格式如下,用于将新元组插入指定表中。需要注意
INTO
子句中没有出现的属性列,新元组在这些列上将会取NULL
- 若
INTO
子句中没有指明任何属性列名,则新插入的元祖必须在每个属性列上均有值
例子:将一个新学生元组 (学号:200215128;姓名:陈冬;性别:男;所在系:IS;年龄:18 岁) 插入到 Student 表中
1 | INSERT |
插入多条记录
1 | INSERT |
# 二,修改数据 (UPDATE)
语法:格式如下,其功能是修改指定表中满足 WHERE
子句条件的元组
- 如果省略 WHERE 子句,则表示要修改表中所有元组
例子:将学生 201215121 的年龄改为 22 岁
1 | UPDATE student |
修改多个元组的值:将所有学生的年龄增加一岁
1 | UPDATE student |
# 三,删除数据 (DELETE)
语法:格式如下,其功能是从指定表中删除满足 WHERE
子句条件的所有元组,注意
DELETE
删除的是表的数据,而不是表的定义- 如果省略
WHERE
子句,那么就表示删除全部元组
注意事项:在进行数据库数据的更新时,需要保证数据库的一致性,以及约束条件
# 视图
# 一,关于视图
【定义】视图是一个虚表,其本质就是一条 SELECT
语句,而查询结果被赋予了一个名字,也即视图名字。或者说视图本身不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发生变化时,视图数据也随之变化。其目的就是在于方便,简化数据操作。
视图的作用:
- 视图能够简化用户的操作
- 视图使用户能以多种角度看待同一数据
- 视图对重构数据库提供了一定程度的逻辑独立性
- 视图能够对机密数据提供安全保护
- 适当的利用视图可以更清晰的表达查询
# 二:视图的定义和删除
1, 视图的定义
语法:使用 CREATE VIEW
语句创建视图,格式如下
- 子查询可以是任意的
SELECT
语句(是可以含有ORDER BY
子句和DISTINCT
短语取决于具体系统) - 组成视图的属性列名要么全部省略要么全部指定,不能有第三种情况
- 如果省略视图列名,则其列名默认由
SELECT
子句目标列诸字段组成
例子:建立信息系 IS 学生的视图
1 | CREATE VIEW IS_student |
视图也可以基于多个表,同一,视图可以基于视图创建,也可以带有表达式。
例子:定义一个反映学生出生年份的视图
1 | CREATE VIEW birthday(Sno,Sname,Syear) |
注意:在定义视图时如果有 WITH CHECK OPTION
子句,则在对视图进行 UPDATE,INSERT,DELETE 时要保证更新,插入,删除的行满足视图定义的谓词条件。
2,视图的删除
- 基本表删除之后,由该基本表导出的所有视图均无法使用,但是视图的定义没有从字典中清除
1 | DROP VIEW <视图名> [CASCADE]; |
# 三,视图的查询
语法:从用户角度出发,查询视图和查询基本表相同;从 DBMS 角度出发,采用视图消解法,具体来讲
- 首先进行有效性检查
- 接着转换成等价的对基本表的查询
- 最后执行修正后的查询
# 四,视图的更新
语法:视图是虚表,所以对视图的更新最终会转化为对基本表的更新。为了防止用户通过视图对数据进行更新时,有意或无意地对不属于视图范围内的基本表数据进行操作,可以在定义视图时加上 WITH CHECK OPTION
子句。这样在更新时,如果不满足条件,DBMS 会拒绝操作
(1)UPDATE
例如:如果在定义视图 is_student
在定义时加入了 WITH CHECK OPTION
子句,接着再执行
1 | UPDATE is_student |
那么在更新时如果将 Sdept
字段改为了’MA’或其他值,DBMS 就会拒绝执行。
(2)INSERT
向信息系学生视图 IS_Student
中插入一个新的学生记录:201215129,赵新,20 岁
1 | INSERT INTO is_student |
- 这里视图没有数据,且 20 插入到了错误的地方(如果没有
WITH CHECK OPTION
就会导致这些错误出现) - 如果假如了
WITH CHECK OPTION
,那么 DBMS 会拒绝执行
(3)DELETE
删除数据时,有没有WITH CHECK OPTION
是一样的。
# 四,数据库完整性
【定义】数据库完整性是指数据的正确性和相容性。
- 正确性:数据是符合现实世界语义、反映当前实际状况的。例如性别只能是男或女
- 相容性:是指数据库同一对象在不同关系表中的数据是符合逻辑的。比如说年龄一般都在 1-100 岁,当然也有超过一百岁的,反正没有两百岁,三百岁成仙的人类
数据库完整性和安全性的区别: - 完整性:是为了防止数据库中存在不符合语义的数据,也就是防止数据库中存在不正确的数据。因此,完整性检查和控制的防范对象是不合语义的、不正确的数据,防止它们进入数据库
- 安全性:是保护数据库防止恶意破坏和非法存取。因此,安全性控制的防范对象是非法用户和非法操作,防止他们对数据库数据的非法存取
** 为维护完整性 DBMS 必须要实现的功能 - 提供定义完整性约束条件的机制
- 提供完整性检查的方法
- 进行违约处理
# 数据库三大完整性
# 一,实体完整性
若属性 A 时基本关系 R 的主属性,则属性 A 不能取空值
(1)定义实体完整性
定义方法:关系模型的实体完整性在 CREATE TABLE
中用 PRIMARY KEY
定义。注意:
- 如果主码仅有一个属性(单属性):可以定义为列级约束条件也可以定义为表级约束条件
- 如果主码有多个属性:注意仅能定义为表级约束条件
(2)实体完整性的检查和违约处理 - 检查主码值是否唯一,如果不唯一则拒绝插入或修改
- 检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改
其中检查记录中主码值是否唯一有两种方法: - 全表扫描:十分耗时
- 建立索引:关系数据库管理系统一般都会在主码上自动建立一个索引
# 二,参照完整性
(1)定义参照完整性
定义方法:关系模型的参照完整性在 CREATE TABLE
中用 FOREIGN KEY
定义,同时用 REFERENCES
短语指明这些外码参照哪些表的主码
定义 sc
表的时候,其 (Sno,Cno)
是主码,分别参照 Sudent
的主码和 Course
表的主码:
1 | CREATE TABLE SC |
(2)参照完整性检查和违约处理
A:破坏完整性的行为
参照完整性将表与表联系在了一起,所以对其中一个表的修改很可能会影响到另外一张表。举个例子,被参照表是 Student
,参照表是 sc
,破坏参照完整性的行为及其违约处理如下表所示:
对于参照表 sc
的行为:
- 向
sc
表(参照表)中插入一个元组,这是会被拒绝的。因为有可能你所插入的元组的Sno
(外码)无法在Student
表中找到,这就意味着在成绩表中插入了一个非本班同学的成绩,这显然是不合理的 - 修改
sc
表(参照表)中的一个元组,这是会被拒绝的。因为有可能你会修改该元组的Sno
(外码),这就可能导致Sno
无法在Student
表中找到。 - 删除
sc
表(参照表)中的一个元组,这是可行的。因为它无非就是一条成绩信息。
对于被参照Student
的行为: - 删除
Student
表(被参照表)中的一个元组,这是会被拒绝(也有可能级联删除或设为NULL
)的。因为删除一个元组后,该元组所对应的Sno
(主码)将不复存在,这就有可能导致sc
表(参照表)中某些元组的Sno
(外码)在Student
表中找不到。当然可以级联删除将 SC 表的相关内容一起删除。 - 修改
Student
表(被参照表)中的一个元组,这是会被拒绝(也有可能级联删除或设为NULL
)的 。因为一旦修改了该元组的Sno
属性,就会发生和上面一样的问题。可以进行级联修改,这回导致 SC 表中的数据也被修改 - 向
Student
表(被参照表)插入一个元组,这是可行的。因为它无非就是一个新同学嘛
B,违约处理措施
①拒绝:不允许操作,为默认策略
②级联:上述提到了。级联删除或修改会影响到其他与他相关的表的数据。
③设为空值:当删除或修改专业
表(被参照表)的一个元组时造成了不一致,则将学生
表(参照表)中的所有造成不一致的元组的对应属性(专业号)设为空值 - 比如删除
专业
表中专业号为 12 的专业,那么接着就要把学生
表中专业号 = 12 的所有元组的专业号设置为空值
C:SQL 实现
1 | CREATE TABLE SC |
# 三,用户自定义完整性
用户自定义完整性针对某一具体关系数据库的约束条件,反映某一具体应用所涉及的数据必须满足的语义要求
(1)属性上的约束条件
A: 不允许取空值 (NOT NULL)
1 | CREATE TABLE SC |
B:列值唯一(UNIQUE)
1 | CREATE TABLE DEPT |
C:满足指定条件(CHECK)
1 | CREATE TABLE Student |
(2)元组上的约束条件
同属性值限制相比,元组级的限制可以设置不同属性之间的取值的相互约束条件
如,规定插入男性时,其名字不能以 Ms.
开头
1 | CREATE TABLE Student |
# 约束命名子句,断言和触发器
这里老师的 PPT 似乎没有讲,先放一放,先找讲过的复习 :)
# 五,数据库安全性
这一章概念的东西好多,也不清除是不是需要记什么的
【定义】保护数据库以防止不合法使用所造成的数据泄露,更改或者破坏
# 数据库安全性概述
# 一,数据库的不安全因素
1. 非授权用户对数据库的恶意存取和破坏: 一些黑客和犯罪分子在用户存取数据库时猎取用户名和用户口令,然后假冒合法用户偷取、修改甚至破坏用户数据。防范措施有:
- 用户身份鉴别
- 存取控制
- 视图
2. 数据库中重要或敏感的数据被泄露: 黑客和敌对分子千方百计盗窃数据库中的重要数据,一 - 些机密信息被暴露。防范措施有 - 强制存取控制
- 数据加密存储
- 加密传输
3. 安全环境的脆弱性
# 二:数据库安全性控制
数据库安全性控制的常用方法:
- 用户标识和鉴定(Identification & Authentication): 系统提供的最外层安全保护措施
- 存取控制:访问权限(授权 和 约束)
- 通过视图调整授权 :定义可向用户授权数据库特定部分的用户视图
- 审计:追踪信息,重现导致数据库现有状况的一系列事件
- 密码存储:使用加密技术保护机密数据
# 1,用户身份鉴别
每个用户在系统中都有一个用户标识。每个用户标识由用户名(user name)和用户标识号(UID)组成。系统内部记录着所有合法用户的标识,每次用户进入系统时,系统会核对用户的身份,只有通过鉴定后才提供相关数据库管理系统的权限
(1)静态口令鉴别
(2)动态口令鉴别
(3)生物特征鉴别
(4)智能卡鉴别
# 2,存取控制
存取控制的目的就是确保只授权给有资格的用户访问数据库的权限,其余人等无法接近数据。主要包括以下两个部分
- 定义用户权限:用户对某一数据对象的操作权力称为权限。某个用户应该具有何种权限是个管理问题和政策问题,而不是技术问题。数据库管理系统的功能是保证这些决定的执行。为此,数据库管理系统必须提供适当的语言来定义用户权限,这些定义经过编译后存储在数据字典中,被称做安全规则或授权规则
- 合法权限检查:每当用户发出存取数据库的操作请求后 (请求一般应包括操作类型、操作对象和操作用户等信息),数据库管理系统查找数据字典,根据安全规则进行合法权限检查,若用户的操作请求超出了定义的权限,系统将拒绝执行此操作
而存取控制方法又分为以下两类:
# (1)自主存取控制 DAC
A,基本概念
自主存取控制 DAC:SQL 中自主存取控制主要是通过 GRANT
语句和 REVOKE
语句来实现的。是指用户可以 “自主” 地决定将数据的存取权限授予何人、决定是否也将 “授权” 的权限授予别人。
授权:用户权限由数据库对象和操作类型这两个要素组成。定义一个用户的存取权限就是定义这个用户可以在哪些数据对象上进行哪些类型的操作。所谓授权就是指定义存取权限
- 在非关系系统中,用户只能对数据进行操作,存取控制的数据库对象也仅限于数据本身
- 在关系数据库系统中,存取控制的对象不仅有数据本身 (基本表中的数据、属性列上的数据),还有数据库模式 (包括数据库、基本表、视图和索引的创建等)
下表就是关系数据库中的主要存取权限:
B:GRANT 与 REVOKE
SQL 中使用GRANT
和REVOKE
语句向用户授予或收回对数据的操作权限
①:GRANT
语法:格式如下,其含义为授予指定用户对指定操作对象的指定操作权限。注意 - 如果指定了
WITH GRANT OPTION
子句,则获得某种权限的用户还可以把这种权限再授权给其他用户。但不允许循环授权 - 如果未指定
WITH GRANT OPTION
子句,则获得某种权限的用户只能使用但无法传播
1 | grant <权限>[,<权限>]… |
- 如果要授权所有权限,可以写
ALL PRIVILEGES
- 如果所有用户接受权限,可以写
PUBLIC
以下对象可以发出GRANT
- DBA
- 数据库对象的创建者
- 已经拥有该权限的用户
下面给出几个例子作为演示:
把查询 Student 表的权限授权给用户 U1:
1 | GRANT SELECT |
把对表 SC 的查询权限授予所有用户
1 | GRANT SELECT |
把对表 SC 的 INSERT 权限授予 U5 用户,并允许将此权限再授予其他用户
1 | GRANT INSERT |
②:REVOKE
- 如果加入
CASCADE
,表示收回某用户权限的同时也会把该用户所有授权过用户的权限一并收回
1 | revoke <权限>[,<权限>]… |
③:创建数据库模式的权限
前面所讲到都是对数据的操作权限,而对创建数据库模式类的数据库对象的授权则由数据库管理员在创建用户时实现
语法:使用 CREATE USER
语句创建用户,其格式如下。注意
- 只有系统的超级用户才有权创建一个新的数据库用户
- 新创建的数据库用户有三种权限:
CONNECT
、RESCOURCE
、DBA
C, 数据库角色
是被命名的一组与数据库操作相关的权限,也即角色是权限的集合。在创建用户时如果为其赋予某种角色,那么用户就自动拥有了该数据库角色所拥有的权限,从而省去了繁琐的授权语句
综合演示:
1 | //首先需要创建一个角色R1 |
# (2)强制存取控制 MAC -ppt 上扩展内容
先放一放,老师 PPT 似乎也没有讲到
# 3,视图
通过视图机制把要保密的数据对无权存取的用户隐藏起来,从而自动对数据提供一定程度的安全保护。 其主要的功能在于提供数据独立性。
在实际应用中通常是视图机制和授权机制进行配合使用。
这里给出一个例子:
在某大学中,假定王平老师只能检索计算机系学生的信息,系主任张明具有检索和增删改计算机系学生信息的所有权限
1 | CREATE VIEW CS_Student |
# 4,审计 -ppt 上扩展内容
没讲
# 5,数据加密 -ppt 上扩展内容
没讲
# 三,数据库产品安全性控制介绍 - 了解
这个是 PPT 上有,课本上没有的
后面补充
# 六,查询处理与查询优化
# 查询处理
【定义】 查询处理是关系数据库管理系统执行查询语句的过程,其任务是吧用户提交给关系数据库管理系统的查询语句转化为更为高效的查询执行计划。
# 一,查询处理步骤
关系数据库管理系统查询处理可以分为 4 个阶段:
- 查询分析
- 查询检查
- 查询优化
- 查询执行
(1)查询分析
任务:对查询语句进行扫描,分析词法、语法是否符合 SQL 语法规则 - 如果没有语法错误转入下一步
- 如果有语法错误则在报告中显示错误
(2)查询检查
任务: - 对合法的查询语句进行语义检查,即根据数据字典中有关的模式定义检查语句中的数据库对象,如关系名、属性名是否存在和有效
- 如果是对视图的操作,则要用视图消解方法把对视图的操作转换成对基本表的操作
- 还要对权限、完整性约束进行检查,如果违反则拒绝查询
- 检查通过后,把 SQL 查询语句转化为内部表示,也即等价的关系代数表达式
- 在此过程中,要把数据库对象的外部名称换为内部表示
- RDBMS 一般用查询树(又称为语法分析树)来表示扩展的关系代数表达式
(3)查询优化
任务:每个查询都会有许多可供选择的执行策略和操作算法,查询优化就是选择一个高效执行的查询处理策略。按照优化的层次一般可以将查询优化分为 - 代数优化:是指关系代数表达式的优化,也即按照一定规则,通过对关系代数表达式进行等价变换,改变代数表达式中操作的次序和组合,使查询更高效
- 物理优化:是指存取路径和底层操作算法的选择。选择依据可以是基于规则的 (rule based)、基于代价的 (cost based)、基于语义的 (semantic based)
(4)查询执行
依据优化器得到的执行策略生成查询执行计划,由 代码生成器 (code generator) 生成执行这个查询计划的代码,然后加以执行,回送查询结果。
# 二,实现查询操作的算法实例
# (1)选择操作的实现
以简单的单表为例,如下
1 | SELECT* FROM STUDENT WHERE<条件表达式> |
<条件表达式>
可以有以下几种情况:
- case1:无条件
- case2: Sno = ‘20214132’
- case3: Sage > 20
- case4 Sdept = ‘CS’ AND Sage > 20
选择操作只涉及一个关系,典型的实现方法有:
# ①全表扫描
思想:假设可以使用的内存块为 M 块
- 按照物理次序读取
Student
的 M 块到内存 - 检查内存的每个元组 t,如果 t 满足选择条件,则输出 t
- 如果
Student
还有其他块未被处理,重复即可
优缺点: - 优点:只需要很少的内存(最少为 1 块)就可以运行,且控制简单。适用于规模较小的表
- 缺点:对于规模大的表进行顺序扫描,当选择率低的时候会使效率很低
# ②索引扫描
思想:如果选择条件的属性上有索引(B + 树或者 hash 索引),可以用索引扫描。通过索引先找到满足条件的元组指针,再通过元组指针在查询的基本表中找到元组。
- 以 case2 为例:Sno = '20214132’并且 Sno 上有索引,则可以使用索引得到 Sno 为 \20214132 元组的指针,然后通过元组指针在 Student 表中检索到该学生
- 以 case3 为例:Sage>20,并且 Sage 上有 B + 树索引,则可以使用 B + 树索引找到 Sage=20 的索引项,以此为入口点在 B + 树的顺序集上得到 Sage>20 的所有元组指针,然后通过这些元组指针到
Student
表对中检索到所有年龄大于 20 的学生。 - 以 case4 为例:Sdept = ‘CS’ AND Sage > 20,如果
Sdept
和Sage
上都有索引,一种算法是:分别用上面的两种方法找到 AND 左右的两个句子,取两组指针的交际,再到 Student 表中检索,就得到计算机系年龄大于 20 的学生
# (2)连接操作的实现 重点题型
连接操作是查询处理中最常用也是最耗时的操作之一 。不失一般性,这里通过例子简单介绍 等值连接 (或自然连接) 最常用的几种算法思想
# ①:嵌套循环方法(nested loop)
思想:对外层循环 ( Student
表) 的每一个元组,检索内层循环 ( SC
表) 中的每一个元组,并检查这两个元组在连接属性 ( Sno
) 上是否相等。如果满足连接条件,则串接后作为结果输出,直到外层循环表中的元组处理完为止
# ②:排序 - 合并方法(sort-merge join)
- 如果参与连接的表没有排好序,首先对
Student
表和SC
表按连接属性Sno
排序 - 取 Student 表中第一个
Sno
, 依次扫描SC
表中具有相同Sno
的元组,把它们连接起来 - 当扫描到
Sno
不相同的第 一个 SC 元组时,返回Student
表扫描它的下一 个元组,再扫描SC
表中具有相同Sno
的元组,把它们连接起来
重复上述步骤直至Student
扫描完毕
# ③:索引连接(index join)
思想:
- 在
SC
表上已经建立了属性Sno
的索引 - 对
Student
中每一个元组,由Sno
值通过SC
的索引查找相应的SC
元组 - 把这些
SC
元组和Student
元组连接起来
循环执行第二步和第三步,直至Student
中的元组处理完毕
# ④:哈希连接(hash join)
思想:它把连接属性作为 hash 码,用同一个 hash 函数把 Student
表和 SC
表中的元组散列到 hash 表中
- 划分阶段(创建阶段):即创建 hash 表。对包含较少元组的表 ( 如
Student
表) 进行一遍处理,把它的元组按 hash 函数 (hash 码是连接属性) 分散到 hash 表的桶中 - 试探阶段(连接阶段):对另一个表 (
SC
表) 进行一遍处理,把SC
表的元组也按同一个 hash 函数 (hash 码是连接属性) 进行散列,找到适当的 hash 桶,并把SC
元组与桶中来自Student
表并与之相匹配的元组连接起来。
# 查询优化
# 一,查询优化概述
(1)查询优化的地位和重要性
关系系统的查询优化既是关系数据库管理系统实现的关键技术,又是关系系统的优点所在。
在非关系系统中,用户必须了解存取路径,系统提供用户选择存取路径的手段,查询的效率由用户的存取策略决定,且系统是无法加以优化的。这就要求用户需要具有较高的数据库技术和程序设计水平
查询优化的优点不仅在于用户不必考虑如何最好地表达查询以获得较高的效率,而且在于系统可以比用户程序的 “优化” 做得更好。
- 优化器可以从数据字典中获得很多统计信息,但是用户程序难以获得
- 即便数据库物理统计信息改变,系统也可以进行优化从而选择相应的执行计划,但是对于非关系系统则必须要重写程序
- 优化器可以考虑数百种不同的执行计划,但程序员一般仅能考虑有限的几种可能性
- 优化器包含了很多复杂的优化技术,这样就等同于所用的使用者间接拥有了这些技术
(2)执行代价
目前关系数据库管理系统通过某种代价模型计算出各种查询执行策略的执行代价,然后选取代价最小的执行方案。一般来说:总代价 = I/O 代价 + CPU 代价 + 内存代价 + 通信代价 - 计算查询代价时一般用查询处理读写的块数作为衡量单位
# 二,一个例子
可以通过 “求选修了 2 号课程的学生姓名” 这样一个例子来说明为什么要进行查询优化
以下是一些系统假设
- 假定学生 - 课程数据库中有 1 000 个学生记录,10 000 个选课记录(平均每一个学生了选了 10 门课),其中选修 2 号课程的选课记录为 50 个
- 有 7 个内存块(其中分配 5 块用于装入
Student
表,1 块用于装入SC
表,1 块用于装入中间结果) - 其中一块可以装入 10 个
student
元组(或 10 个student
与 SC 笛卡尔积元组);一块也可以 装入 50 个 SC 元组(因为 SC 的列数较少) - 连接方法为:基于数据块的嵌套循环法。
- 之所以这样分配的原因:因为嵌套循环算法需要选用占用内存少的表作为外表,student 表有 1000 行,每块装 10 行,所以需要 100 块;SC 表有 10000 行,每块装 50 行,所以需要 200 块。
- 由于 student 表需要 100 个内存块,而分配给它的只有 5 个,所以不可能一次全部装入内存,每次只能装入一部分,比较完了再装入另外一部分。每换一批数据,内标就需要全部重新装入以便,所以为了减少内表循环装入的次数,就必须尽可能的分配内存给外表
- 连接后的元组装满一块后就写到中间文件上
1 | SELECT Student.name |
系统可以用多种等价的关系代数表达式来完成这一查询,这里只举三种情况
# (1)情况 1
Student
与 Sc
作笛卡尔积,而后作行选择运算(选择条件为 Student.Sno=SC.Sno AND SC.Cno='2'
),最后进行投影操作
①:计算广义笛卡尔积
操作:
- 在内存中尽可能多地装入某个表 (如
Student
表) 的若干块,留出一块存放另一个表 (如SC
表) 的元组; - 然后把
SC
中的每个元组和Student
中每个元组连接,连接后的元组装满一块后就写到中间文件上,再从SC
中读入一块和内存中的Student
元组连接,直到SC
表处理完; - 这时再一次读入若干块
Student
元组,读入一块SC
元组,重复上述处理过程,直到把Student
表处理完
块数: - 读一遍
Student
表所需块数为 = 1000/10 = 100 块 - 读一遍
SC
表所需要块数为 = 10000/50 = 200 块 - 由于
Student
表可用块数为 5 块,所以分 100/5 = 20 次读入 - 同时,
Student
表的每一部分读入内存时,SC
表都需要重新读一遍,以此完成与Student
表的连接。所以需要读入 200×20=4000 块 - 所以笛卡尔积读取总块数为 100+4000=4100 块
- Student 表和 SC 表做笛卡尔积共 107 行,每块装 10 行,所以中间结果块数 106 块(写入)
②作选择操作
块数: - 所读块数为 10^6 块
- 选择后的结果只有 50 个
③作投影操作 - 无需读写
情况 1 读取总块数:
4100(读)+106(写)+106(读)。约为 200 万块
# (2)情况 2
Student
与 Sc
作自然连接,而后作行选择运算(选择条件为 Student.Sno=SC.Sno AND SC.Cno='2'
),最后进行投影操作
①:计算自然连接
块数:
- 首先读
Student
和SC
,与情况 1 一致。因此总块数 = 4100 块 -
Student
和SC
自然连接后右 10000 行,所以中间结果块数 ** 10000/10 = 1000 块
②选择操作 - 读入中间结果,块数 = 1000 块
③:作投影操作 - 50 个结果可以不用写入
情况 2 的总读取块数:
4100(读) + 1000(写) + 1000 (读) 共计 6100 块
# (3)情况 3
首先 Sc
作行选择(选择条件为 SC.Cno='2'
),而后作自然连接运算,最后进行投影操作
块数:
- 先对
SC
表作选择操作,只需读一遍SC
表,存取块数为 100 块,因为满足条件的元组仅 50 个,不必使用中间文件 - 读取
Student
表,把读入的Student
元组和内存中的SC
元组作连接。也只需读一遍Student
表,共 100 块,把连接结果投影输出
总数:共计 300 块
# 查询优化之代数优化
【概念】 代数优化是指关系代数表达式的优化,1 即按照一定规则,通过对关系代数表达式进行等价变化,改变代数表达式中操作的次序和组合,使查询更加高效
# 关系代数表达式的等价变化规则
(1)连接,笛卡儿积,并,交的交换律
很简单,即上述几种运算都是可交换的,即两个集合进行上述运算,其前后位置可以发生改变。
(2)连接,笛卡儿积,并和交的结合律
同理,和集合的结合律一样,这里不再阐述。
(3)投影的而串接定律
关系的两次投影操作可以合并成为一次操作
((E)) ≡ (E)
(4)选择的串接定律
选择的两次投影操作可以合并为一次完成
((E)) ≡ (E)
(6)选择与笛卡儿积的交换律
① ( × ) = () ×
对于选择条件只与其中一个关系有关,则应该先对那个关系做出选择,然后再做笛卡儿积。
②( × ) = () × ()
选择条件对两个关系都有关,则应该先分别做选择,然后再做笛卡尔积。
# 查询树的启发式优化
- 这是对关系代数表示的查询树进行优化的方法
# 典型的启发式规则
- 【规则 1】选择运算应尽可能先做:这是为了减少中间结果的规模
- 【规则 2】投影和选择运算同时进行:这是为了避免重复扫描
- 【规则 3】将投影运算与其前后的双目运算结合起来:这是为了避免重复扫描
- 【规则 4】把某些选择运算和其前面的笛卡尔积结合起来成为一个连接运算:这是为了减少中间结果的规模
- 【规则 5】提取公共子表达式(公因子):这是为了保存计算结果,避免重复计算
# 实现算法
- 该算在遵循启发式规则,并应用关系代数表达式等价变换规则来优化关系表达式
- 该算法的输入和输出都是查询树(分别对应待优化和优化的关系表达式)
算法步骤: - 【步骤 1】分解选择运算:这是为了便于不同的选择运算沿树的不同分枝向树叶移动,一直移动到与这个选择条件相关的关系处,使选择尽可能先做
# 七,并行控制技术
# 并发控制技术概述
事务:指用户定义的一个数据库的操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
- 原子性:事务中包括的操作要么都做,要么都不做
- 一致性:事务执行的结果是从一个一致性状态转变到另一个一致性状态
- 隔离性:一个事务的执行不应该被其他事务干扰
- 持久性:事务成功后,对数据库的改变是永久的,即使以后系统出现故障也不会影响。
给出事务运行的方式:串行和并行 - 串行:每个时刻只有一个事务运行 (优点:实现简单,保证事务一致性。缺点:效率低)
- 并行:同一个时刻可以有多个事务同时运行(优点:效率高,提高整个系统吞吐量,减少平均响应时间。缺点:破坏事务隔离性,导致数据库不一致性)
emm 这里给出 ppt 上讲的并行和并发的区别 - 并行:多个处理器或者是多核的处理器同时处理多个不同的任务,物理上的同时发生
- 并发:一个处理器同时处理多个任务,逻辑上的同时发生
# 并发控制
# (1)并发控制带来的数据不一致行问题
以如下飞机订票系统中的活动序列为例
①甲售票点 (事务)读出某航班的机票余额 A,设 A=16
②乙售票点 (事务)读出同一航班的机票余额 A,也为 16。
③甲售票点卖出一张机票,修改余额 A←A-1,所以 A 为 15,把 A 写回数据库。
④乙售票点也卖出一 - 张机票,修改余额 A-A-1,所以 A 为 15,把 A 写回数据库。
A. 丢失修改
指两个以上事务从数据库中读入同一个数据并修改,其中后提交的事务的提交结果破坏了前提交事务的提交结果,导致了先提交事务对数据库的修改丢失。
B. 读脏数据
事务 1 修改某一数据,并将其写回磁盘;事务 2 读取同一数据后,事务 1 犹豫某种原因被撤销,这时事务 1 已经修改过的数据被恢复为原值,事务 2 读到的不稳定的瞬间数据就与数据库中的数据产生了不一致,是不正确的数据,又称为脏数据
C. 不可重复读
事务 1 读取数据后,事务 2 执行了对读取数据的更新操作,事务 1 再次读取时无法再现上一次读取的结果。
# (2)并发控制概念
如果多个用户并发存取数据的行为不加以控制,那么极有可能破坏事务的隔离性和一致性。因此并发控制就是为了保证多用户并发操作数据库中信息的正确性,一致性所采取的措施。
# 封锁,封锁协议活锁和死锁
# 一,封锁
【概念】封锁就是事务 T 在对某个数据对象操作之前,先向系统发出请求,对其加锁;加锁后事务 T 对该数据对象就有了一定的控制,在事务 T 释放它的锁之前,其他事务不能更新此数据对象。
【类型】
- 排他锁(X 锁):又称为写锁,若事务 T 对数据对象 A 加上 X 锁,则只允许 T 读取和修改 A,其他任何事务都不能再对 A 加任何类型的锁,直到 T 释放 A 上的锁
- 共享锁(S 锁):又称读锁,若事务 T 对数据对象 A 加上 S 锁,则其他事务只能再对 A 加 S 锁,而不能加 X 锁,直到 T 释放 A 上的 S 锁
附加:锁升级 - S 锁允许多个事务同时访问同一个数据对象 A,即允许更多的并发操作。这里我们可以让事务 T 先读取数据对象 A 后写入 A 的新值操作时,可以先申请 S 锁,当要写入时再将锁升级为 W 锁。
优点:提高并发执行效率 缺点:增加死锁的可能性
# 二,封锁协议
【概念】是指再运用 X 锁和 S 锁对数据对象加锁时需要遵照的一些规则。例如,何时申请,持续时间和何时释放等。不同的封锁协议,为并发操作的正确调度提供了一定的保证,所能达到的系统一致性级别也是不同的。常用的封锁协议有:
- 支持一致性维护的三级封锁协议
- 支持并行调度可串行化的两端封锁协议
①一级封锁协议
事务 T 在修改数据 R 之前必须先对其加 X 锁,直到事务结束才释放 - 防止丢失修改
- 不能保证可重复读和不读脏数据
②二级封锁协议
在一级封锁协议的基础上,增加事务 T 在读取数据 R 之前必须先对其加上 S 锁,读取完成之后即可释放 S 锁 - 可以防止丢失修改和读脏数据
- 不能保证可重复读
③三级封锁协议
是指在一级封锁协议的基础上增加事务 T 在读取数据 R 之前必须对其加 S 锁,直到事务结束时才可以释放 S 锁 - 放置了丢失修改和读脏数据,还防止了不可重复读
# 三,饥饿,活锁和死锁
一个问题的解决必然会导致另一个问题的出现。封锁技术可以有效地解决并发操作的一致性问题,但是会带来新的问题
- 饥饿:由于不同锁的类型导致的,有希望获得排他锁,但由于不断获得共享锁可能永远等待
解决方法:事务 T 申请对数据项 R 加 M 型锁,允许加锁的条件:1,在 R 上不存在与 M 冲突的锁的其他事务。2,不存在等待对 R 加锁,且先于 T 申请加锁的事务 - 活锁:由于调度顺序的随机性导致,有希望获得锁,但是由于调度顺序的选择,可能永远等待
解决方法:1,封锁管理子系统按照请求封锁的先后顺序对事务排队 2,一旦被申请的数据对象的锁释放,立即批准队列中的一个事务获得锁 - 死锁:由于调度顺序的随机性导致,两个事务同时申请对方正在使用的数据资源,导致相互等待
死锁的解决方法:预防和检测
预防(不可行):一次封锁,顺序封锁,基于时标的抢占和事务撤销技术
检测(DBMS 常用方法):超时法:一个事务等待的时间超过了规定的时间,就认为其发生了死锁
等待图法:用一个有向图 G,节点表示正在执行的事务,边表示等待情况。如果图中存在回路,则表示发生死锁。
检测后的诊断和修复
- 因素 1:选择一个处理死锁代价最小的事务,将其撤销,释放锁
- 因素 2:决定 rollback 多远。彻底撤销或者 rollback 到可以解决死锁为止。
- 因素 3:避免饥饿,避免因为某个事务 rollback 代价最小而一直被 rollback,在代价因素中包括事务的 rollback 次数即可解决。
# 四,并发调度的可串行性,两段锁协议和封锁的粒度
# 一,可串行化调度
【概念】多个事务的并发执行是正确的,当且仅当其结果与某一次按次序串行执行这些事务时的结果相同,称这种调度策略为可串行化调度。可串行性是并发事务正确调度的准则,也即一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度。
冲突操作:是指不同事务对同一个数据的读写操作和写写操作。除此之外,其他操作均为不冲突操作。
冲突可串行化:一个调度 SC 在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度 SC,如果 SC 是串行的,则称调度 SC 为冲突可串行化的调度。若一个调度是冲突可串行化的,那么它一定是可串行化的调度。
# 二,两段锁协议
两端锁协议是三级封锁协议的特例,目前 DBMS 普遍采用该种协议实现并发调度的可串行性。具体内容如下:
- 在对任何数据进行读,写操作之前,首先要申请并获得对该数据的封锁
- 在释放一个封锁之后,事务不再申请和获得任何其他封锁
其中‘两段’是指事务分为两个阶段: - 第一阶段:获得封锁,也称为扩展阶段。如果该数据项被其他使用者加上不相容的锁,则必须等待。
- 第二阶段:释放封锁,也成为收缩阶段。事务在释放锁后,不允许再申请其他锁。
# 三,封锁的粒度
【概念】是指封锁对象的大小。封锁对象可以是逻辑单元,也可以是物理单元。封锁粒度与系统并发度和并发控制的开销密切相关,一般来说,封锁粒度越大,数据库所能封锁的数据单元就越少,并发度越小,开销就越小。
- 逻辑单元:元组,关系,整个数据库等
- 物理单元:页,物理记录等
选择封锁的原则 - 需要处理多个关系的大量元组的用户事务时以数据库为封锁单位
- 需要处理大量元组的用户事务时以关系为封锁单元
- 只处理少量元组的用户事务时以元组为封锁单位
多粒度封锁:在一个系统中同时支持多种封锁粒度供不同的事务选择
# 基于时标的并发控制
# 基于时间标记确定并发执行的事务中操作执行顺序
- 根据实物的时标确保实际事务的调度等价于串行调度
- 该方法假设没有非串行化行为发生,只在违例时进行修复
- 修复方法:中止并重启视图参与非可串行化的事务
# 时间戳协议的特点
- 由于冲突操作是按照时标顺序处理的,时标顺序协议能保证调度是可串行化的
- 由于没有事务处于等待状态,并发调度不会产生死锁
- 时标顺序协议使调度无级连回退调度(不存在事务重启动)
# 基于封锁和基于时标的并发控制比较
封锁 空间小,技术成熟,特点是推迟事务
时标 空间大,技术不成熟,特点是回滚事务
# 八,数据库恢复技术
# 一,事务的基本概念
事务:是用户定义的一个数据库操作序列。这些操作要么全做,要么不做,是一个不可分割的工作单位。例如在 RDBMS 中一个事务可以是一条 SQL 语句或整个程序。事务是数据库恢复和并发控制的基本单位。一般来说,一个程序中包含多个事务。
事务的定义:事物的开始和结束由用户显式控制。如果用户没有显式地定义事务,则由 DBMS 按默认规定自动划分事务。在 SQL 语句中,定义事务语句有以下三条:
BEGIN TRANSACTION
:表示事务的开始COMMIT
:表示事务的正常结束并提交事务的所有操作ROLLBACK
:表示事务的结束,但没有正常结束,需要进行回滚(撤销已经完成的操作,使系统恢复至回滚前状态)
# 事务的四个特性 ——ACID
A. 数据库的 ACID
①:原子性
事务是数据库的逻辑工作单位,事务中包含的诸多操作或全做或全不做。因故障未能做完的,需要有一套机制用于撤销那一部分已经做了的。
②:一致性
事务执行的结果必须是使数据库从一个一致性状态边到另一个一致性状态
- 一致性状态:数据库中只包含成功事务提交的结果
- 不一致状态:数据库中包含事务未完成时的状态
③:隔离性
一个事务不能被其他事务干扰。也即一个事务的内部操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰
④:持续性
一个事务一旦提交,它对数据库中的数据的改变就是永久性的。接下来的其他操作或故障不应该对其执行结果有任何影响
B: 破坏 ACID 的因素 - 故障:没有执行完;虽然没有完,但是存储介质故障
- 并发干扰:多个事务并行运行时,不同的事务操作交叉执行,互相干扰。破坏了 ACID 中的 I
# 数据库恢复概述
【定义】吧数据库从因破坏或故障而导致的错误状态恢复到某个已知的正确状态的技术
目的:
- 保持事务的原子性
- 保持事务的持久性
# 故障种类
# 一,事务故障
# 事务故障概念
某个个事务在运行过程中由于种种原因未运行到正常终止点就夭折了
# 事务故障原因
- 运算溢出
- 违反了某些完整性约束
# 二,系统故障
# 九,数据库编程
# 数据库编程概念
建立数据库的目的是开发应用系统
SQL 语言特点:
- 非过程化查询语言
- 操作同一,面向集合,功能丰富,使用简单
应用系统使用 SQL 编程访问管理数据库的方式: - 嵌入式 SQL
- 过程化 SQL:PL/SQL
- 存储过程和自定义函数
- 开放数据库连接 ODBC
- JDBC java 数据库连接
# 嵌入式 SQL
# 数据库管理 SQL 的两种方式
- 交互式和嵌入式
嵌入式 SQL: - 将 SQL 语句嵌入程序设计语言中,被嵌入的程序语言成为宿主语言,简称主语言
- 为了进行区分,SQL 语句需要加上前缀
# 数据库应用体系结构
# ODBC 编程
【定义】ODBC 标准是一个接口,通过接口应用程序可以利用独立于 DVMS 的方法来访问数据库和在数据库中处理 SQL。
包括
- 数据源:是一个数据库,包括相关的 DBMS,操作系统,网络平台
- DBMS Driver: 由 dBMS 厂商提供独立的软件公司
- Driver MAnager:应用软件运行的平台,由 O/S 厂商提供
# ODBC 的优缺点
- 优点:互操作能力,应用程序对数据操作不依赖于 DBMS
- 缺点:功能受限:部分驱动器仅仅实现核心 API 函数,功能降低:无法通过 SQL 语句利用数据库优化器
# JDBC 编程
# 十,关系数据库设计
# 问题的提出
# 冗余导致的问题
- 插入异常:
- 删除异常
- 数据冗余
- 更新复杂
解决方法:模式分解
# 规范化
# 数据依赖
数据以来是一个关系内部属性和属性之间的约束关系。这种约束关系是通过属性值的相等与否体现出来的数据间相关联系。它是现实世界属性间相互联系的抽象,体现在关系模式中的各属性之间相互依赖相互制约的关系。
# 函数依赖(最重要)
- 关系模式中属性之间的一种逻辑依赖关系
函数依赖有 非平凡函数依赖,平凡函数依赖,完全函数依赖,部分函数依赖,函数传递依赖。 - 非平凡函数依赖:X 确定 Y,但 Y 不是 X 的子集
- 平凡函数依赖:X 确定 Y,Y 是 X 的子集
- 完全函数依赖:X 确定 Y,那么 X 中的任何一个分量都不能丢。
- 部分函数依赖:X 确定 Y,即便去掉 X 的一个或者多个分量,剩余分量也能确定 Y
- 传递函数依赖:如果 X 是 Y 的非平凡函数依赖,且 Y 不是 X 的函数依赖,同时 Y 是 Z 的非平凡函数依赖,则称 Z 对 X 传递函数依赖。
# 多值依赖
多值依赖就是 X 能够确定一组其他值,例如,一门课程有多个老师,但是一门课程的参考书籍是固定的 ABC,这样的关系可能会产生一些问题:
- 插入异常:增加一名讲课教师时,必须插入多个元组,即每次都要插入三个书籍,故要插入三个元组。
- 删除异常:例如一门课想要删除一本参考书,则要删除所有老师后面对应的参考书
函数依赖是多值依赖的特例
解决方法仍然是模式分解
# 范式
# 第一范式 1NF
【定义】:如果一个关系中的所有属性值均是原子的,则称该关系满足 1NF。直观讲:就是关系中任何一列中不能再分为两列或者更多列。
# 第二范式 2NF
【定义】若 R∈1NF,且每个非主属性(不是候选码中出现的属性)完全依赖于码,则称 R 是第二范式。直观的讲:就是一个表中只能保存一种数据,不能把多种数据保存在同一张表。
# 第三范式 3NF
【定义】关系模式 R<U,F> 中若不存在这样的码 X,属性组 Y 以及非主属性组 Z (Z 不属于 Y),使得 X->Y,Y->Z 和 Y 不确定 X 成立,则称 R 属于 3NF。(即消除非主属性对码的传递性依赖)直观上:就是确保表中的每列数据都和主码直接相关,而不是间接相关。专业定义就是保证每个非主属性码对码既不是部分函数依赖也不是传递函数依赖。
# BCNF
【定义】关系模式 R,若 X 确定 Y 且 Y 不属于 X,X 必含有码,则 R 是 BCNF。直观上讲:BCNF 是修正的第三范式,修正了每一属性对候选码的传递依赖。BCNF 一定是 3NF,3NF 不一定是 BCNF。
- 所有非主属性对每个码都是完全函数依赖
- 所有的主属性对每一个不包含它的码也是完全函数依赖
- 没有任何属性完全函数依赖于非码的任何一组属性
# 4NF
【定义】简单点说,要满足 4NF,那么该关系模式的多值依赖要不是平凡的,如果是非平凡的,就必须退化为函数依赖。就是说非平凡又非函数依赖的多值依赖是不允许存在的
# 数据依赖的公理系统
- 数据依赖的公理系统是模式分解算法的理论基础
- ARMstrong 公理系统:函数依赖的一个有效而完备的公理系统
- 定义:逻辑蕴含:对于满足一组函数依赖 F 的关系模式 R,其中任何一个关系 r, 若函数依赖 X 确定 Y 都成立,则称 F 逻辑蕴含 X 确定 Y。
# 推理规则
设 U 为属性集总体,F 是 U 上的一组函数依赖,于是有关系模式 R<U,F>, 对 R<U,F > 来说有以下推理规则:
- 自反律:若,则 X->Y 为 F 所蕴含
- 增广律:若 X->Y 为 F 所蕴含,则 则 XZ->YZ 为 F 所蕴含
- 传递律:若 X->Y 和 Y->Z 为 F 所蕴含,则 X->Z 为 F 所蕴含。