结合 pjz 学长的笔记做了一些删改。
# 第 1 章 绪论
ppt 01-07
# 1.1 数据库系统概述
# 基本概念
数据 data
- 数据库中存储的基本对象,是描述事物的符号记录。
- 数据的含义称为语义 **,数据与其语义是不可分的。**
- 98 是一个数据
- 可能是我的体重、数据库的分数,等等
数据库 database
- 简称 DB
- 是长期储存在计算机内、有组织的、可共享的大量数据的集合。
- 基本特点
- 数据按一定的数据模型组织、描述和储存
- 具有较小的冗余度(redundancy)
- 较高的数据独立性(data independency)
- 易扩展性(scalability)
- 可为各种用户共享
数据库管理系统 DataBase Management System DBMS
DBMS 的功能(可能出选择)
- 定义
- 组织、存储和管理
- 操纵
- 管理事务和运行管理
- 建立和维护
- 其他,如不同数据库之间的互访和互操作功能
数据库系统 DataBase System DBS
数据库系统的构成:
- 数据库
- 数据库管理系统(DBMS,及其应用开发工具)
- 应用程序
- 数据库管理员(DBA)
# 数据库基本特征【简答】
数据结构化
- 数据内部结构化
- 数据之间具有联系,整体是结构化的
数据的共享性高,冗余度低且易扩充
数据独立性高
- 数据和程序相互不依赖
- 物理独立性
- 数据库存储结构(物理结构)改变,管理员对模式 / 内模式映像作改变,可以使模式不变、外模式不变
- 逻辑独立性
- 模式(逻辑结构)改变,管理员对各个外模式 / 模式的映像作相应改变,可以使外模式保持不变,应用程序不变。
数据由数据管理系统(DBMS)统一管理和控制
- 安全性保护
- 完整性检查
- 并发控制
- 数据库恢复
# 使用数据库系统有什么好处?
# 数据管理方式对比【简答】
# 1.2 数据模型
概念:数据模型是对现实世界数据特征的抽象,用以抽象、表示和处理现实世界中的数据和信息。
数据模型的组成要素:
- 数据结构
- 数据操作
- 数据的完整性约束条件
分类:
- 概念模型
- 按用户的观点来对数据和信息建模,用于数据库设计
- 关系和实体
- 逻辑模型
- 按计算机系统的观点对数据建模,用于 DBMS 实现
- 主要包括网状模型、层次模型、关系模型、面向对象数据模型、对象关系数据模型、半结构化数据模型等。
- 表、索引、逻辑
- 物理模型
- 是对数据最底层的抽象,描述数据在系统内部的表示方式和存取方法。
- mysql 结构,物理设计
# 概念模型
用于数据库设计, 用 E-R 图来描述现实世界的概念模型。
概念:
- 实体
- 客观存在并可相互区别的事物称为实体。
- 可以是具体的人、事、物或抽象的概念。
- 属性
- 实体所具有的某一特性称为属性。
- 一个实体可以由若干个属性来刻画。
- 码
- 唯一标识实体的属性集称为码
- 实体型
- 实体集
- 联系
- 一对一、一对多、多对多
# 概念模型 (E-R 图)
当然也有内部的联系
- 联系也可以有属性
- 实例
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619210012489.png" alt="image-20220619210012489" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619210026931.png" alt="image-20220619210026931" />
- IS-A 联系(考试可能会考)
- Part-of / 独占 / 弱实体
# 逻辑模型
分类:
层次模型
网状模型
关系模型
关系模型必须是规范化的:比如,关系的每个分量必须是一个不可分的数据项
关系模型的优缺点
(要知道,可能会考简答,后面的 nosql 跟关系型数据库的对比也提到了这个知识点)
面向对象数据模型
# 1.3 数据库系统的结构
# 三级结构
三级模式是对数据的三个抽象级别
外模式:数据库用户的数据视图,是与某一应用有关的局部数据的逻辑表示
和模式类似于 VO 和 PO 的关系
模式:数据库中全体数据的逻辑结构和特征的描述
- 公共视图
内模式:是数据在数据库内部的表示方式
- 唯一
# 二级映像
# 外模式 / 模式映像:
- 一对多的关系
- 每一个外模式,数据库系统都有一个外模式/模式映象,定义外模式与模式之间的对应关系
- 当模式改变时,数据库管理员对外模式/模式映象作相应改变,使外模式保持不变。应用程序是依据数据的外模式编写的,应用程序不必修改,保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。
# 模式 / 内模式映像:
- 一对一的关系
- 模式/内模式映象定义了数据全局逻辑结构与存储结构之间的对应关系。
- 当数据库的存储结构改变了(例如选用了另一种存储结构),数据库管理员修改模式/内模式映象,使模式保持不变。应用程序不受影响,保证了数据与程序的物理独立性。
# 1.4 数据库系统的组成
看看就好
组成
- 硬件、软件、人员
# 第 2 章 关系数据库
ppt 08-10
# 2.1 关系数据结构
- 域
笛卡尔积
关系
关系的类型:基本关系、查询表(查询结果对应的表)、视图表(虚表)
基本关系的性质
- 列是同质的:每一列中的分量是同一类型的数据,来自同一个域
- 不同的列可出自同一个域,其中的每一列称为一个属性
- 列和行的顺序无所谓
- 任意两个元组的候选码不能相同
- 分量必须取原子值
关系的每一个分量必须是一个不可分割项
码
这两张表就是数据
而单独的一张表就称为数据对象,即人员表是一个数据对象,课程表也是一个数据对象
而每张表中的每一行就称为数据元素
而姓名,性别,身高,课程代号,课程名就称为数据项
关系模式(型)
关系模式是静态的,关系是动态的。关系是关系模式在某一时刻的状态或内容。
关系数据库:所有关系的集合构成一个关系数据库
- 关系数据库的型:关系数据库模式,是对关系数据库的描述
- 关系数据库的值:关系模式在某一时刻对应的关系的集合,通常称为关系数据库
# 2.2&2.3 关系操作和完整性
查询
- 选择、投影、并、差、笛卡尔积是 5 种基本操作
更新
- 插入、修改、删除
实体完整性:primary key is NOT NULL
- 若属性(指一个或一组属性)A 是基本关系 R 的主属性,则 A 不能取空值(null value)
- 空值就是 “不知道” 或 “不存在” 或 “无意义” 的值
- 原因:如果取了空值,就说明存在某个不可标识的实体,即存在不可区分的实体。
外码:Foreign Key
- R(KR,F, ... ) -> S(Ks, ...)
参照完整性: The value of foreign key is either NULL or in the referenced column
- 四种可能被破坏的情况
- SC 表中增加一个元组,该元组的 Sno 属性的值在表 Student 中找不到一个元组,其 Sno 属性的值与之相等。
- 修改 SC 表中的一个元组,修改后该元组的 Sno 属性的值在表 Student 中找不到一个元组,其 Sno 属性的值与之相等。
- 从 Student 表中删除一个元组,造成 SC 表中某些元组的 Sno 属性的值在表 Student 中找不到一个元组,其 Sno 属性的值与之相等。
- 修改 Student 表中一个元组的 Sno 属性,造成 SC 表中某些元组的 Sno 属性的值在表 Student 中找不到一个元组,其 Sno 属性的值与之相等 。
- 四种可能被破坏的情况
- 用户定义的完整性:应用领域需要遵循的约束条件,体现了具体领域中的语义约束(就是字面意思)
- 比如学生不能没有姓名
- 成绩的取值范围定义在 0-100 之间
# 2.4 关系代数(重点)
见 ppt ch10 或第五版课本 P47,做往年题和课后题!
选择、投影、并、差、笛卡尔积是 5 种基本操作
集合运算符从行的角度看,专门的关系运算符可从行、列的角度看
选择、差、交、并是从行的角度来看,投影是从列的角度来看
- 差是减去相同的行
- 投影包含去重操作
除和自然连接是在行、列的角度上看
连接绝大多数是自然连接
- 自然连接:一种特殊的等值连接,两个关系中比较的分量必须是相同的属性组,且在结果中把重复的属性去掉(去掉重复列)
悬浮元组
- 两个关系 R 和 S 在做自然连接时,关系 R 中某些元组有可能在 S 中不存在公共属性上值相等的元组,从而造成 R 中这些元组在操作时被舍弃了,这些被舍弃的元组称为悬浮元组。
外连接
- 如果把悬浮元组也保存在结果关系中,而在其他属性上填空值 (Null),就叫做外连接
- 左外连接 (LEFT OUTER JOIN 或 LEFT JOIN)
- 只保留左边关系 R 中的悬浮元组
- 右外连接 (RIGHT OUTER JOIN 或 RIGHT JOIN)
- 只保留右边关系 S 中的悬浮元组
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618160358881.png" alt="image-20220618160358881" style="zoom:50%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618160428968.png" alt="image-20220618160428968" style="zoom:50%;" />
- 除运算
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618160725012.png" alt="image-20220618160725012" style="zoom:50%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618160810901.png" alt="image-20220618160810901" style="zoom:50%;" />
# 第 3 章 关系数据库语言 SQL
ppt 11-22
# 3.1 - 3.3 概述和数据定义(操作直接看书)
SQL Structured Query Language 结构化查询语言
SQL 特点
- 综合统一
- 高度非过程化
- 面向集合的操作方式
- 以一种语法结构提供多种使用方式
- 语言间接,易学易用
SQL 功能 动词 数据查询 SELECT 数据定义 CREATE, DROP, ALTER 数据操纵 INSERT, UPDATE, DELETE 数据控制 GRANT, REVOKE 层次化的数据库对象命名机制
- Drop 的 Restrict 和 Cascade
- 数据字典
# 3.4 数据查询(必考)
- 基本语法
- 剩余见课后习题和往年卷!
# 单表查询
- 聚集、GROUP BY 要掌握
- 一定会出一道写 sql 的题
SELECT [ALL | DISTINCT] <目标列表达式> [,<目标列表达式>] ... | |
FROM <tableName> [,<tableName>] ... | (<select_caluse>) | |
[AS] <alias> | |
[WHERE <conditional_expression>] | |
[GROUP BY <colName> [HAVING <conditional_expression>]] | |
[ORDER BY <colName>] [ASC | DESC]]; | |
SELECT Sno, Sname FROM Student; | |
SELECT Sname, Sno, Sdept FROM Student; | |
SELECT Sno, Sname, Ssex, Sage, Sdept FROM Student; | |
SELECT * FROM Student; /* 与上一行等价 */ | |
SELECT Sname, 2014-Sage FROM Student; /* 可以存在表达式 */ | |
SELECT Sname, 'Year of Birth: ', 2014-Sage, LOWER(Sdept) FROM Student; | |
SELECT Sname NAME,'Year of Birth:' BIRTH, 2014-Sage BIRTHDAY, LOWER(Sdept) DEPARTMENT FROM Student; /* 查询结果表头为别名,要求用小写字母表示所在系 */ | |
SELECT ALL Sno FROM SC; = SELECT Sno FROM SC;/* 默认时 ALL*/ | |
SELECT DISTINCT Sno FROM SC;/* 消除取值重复的行 */ | |
/* 比较大小 */ | |
SELECT Sname FROM Student | |
WHERE Sdept=‘CS’; | |
SELECT Sname, Sage FROM Student | |
WHERE Sage < 20; | |
SELECT DISTINCT Sn FROM SC | |
WHERE Grade < 60; | |
/* 确定范围 */ | |
SELECT Sname, Sdept, Sage FROM Student | |
WHERE Sage BETWEEN 20 AND 23; | |
SELECT Sname, Sdept, Sage FROM Student | |
WHERE Sage NOT BETWEEN 20 AND 23; | |
/* 确定集合 */ | |
SELECT Sname, Ssex FROM Student | |
WHERE Sdept IN ('CS', 'MA', 'IS'); | |
SELECT Sname, Ssex FROM Student | |
WHERE Sdept NOT IN ('IS', 'MA', 'CS'); | |
/* 字符匹配 */ | |
SELECT * FROM Student | |
WHERE Sno LIKE '201215121'; /* 匹配固定字符串 */ | |
/* 等价于 */ | |
SELECT * FROM Student | |
WHERE Sno = '201215121'; | |
SELECT Sname, Sno, Ssex FROM Student | |
WHERE Sname LIKE '刘%'; /* % 匹配任意长度(长度可以为 0)字符串 */ | |
SELECT Sname FROM Student | |
WHERE Sname LIKE '欧阳_'; /* _ 匹配任意单个字符 */ | |
SELECT Sname,Sno FROM Student | |
WHERE Sname LIKE '_阳%'; | |
SELECT Sname, Sno, Ssex FROM Student | |
WHERE Sname NOT LIKE '刘%'; /* 查询所有不姓刘的学生姓名、学号和性别。 */ | |
SELECT Cno,Ccredit FROM Course | |
WHERE Cname LIKE 'DB\_Design' ESCAPE '\ '; /* ESCAPE '\' 表示 '\' 为换码字符 */ | |
SELECT * FROM Course | |
WHERE Cname LIKE 'DB\_%i_ _' ESCAPE '\ '; | |
/* 涉及空值的计算 */ | |
SELECT Sno, Cno FROM SC | |
WHERE Grade IS NULL; | |
SELECT Sno,Cno FROM SC | |
WHERE Grade IS NOT NULL; /* 涉及空值的查询:IS (NOT) NULL: IS 不可换成 = */ | |
/* 多重条件查询 */ | |
/* AND 的优先级高于 OR 可以用括号改变优先级 */ | |
SELECT Sname FROM Student | |
WHERE Sdept = 'CS' AND Sage < 20; | |
SELECT Sname, Ssex FROM Student | |
WHERE Sdept IN ('CS', 'MA', 'IS'); | |
SELECT Sname, Ssex FROM Student | |
WHERE Sdept = ' CS' OR Sdept = 'MA' OR Sdept= 'IS'; | |
/* 可以按一个或多个属性列排序 | |
升序:ASC; 降序:DESC; 缺省值为升序 | |
对于空值,排序时显示的次序由具体系统实现来决定 */ | |
SELECT Sno, Grade FROM SC WHERE Cno = '3' | |
ORDER BY Grade DESC; | |
/*Sdept 按升序排列,学生年龄按降序排列 */ | |
SELECT * FROM Student | |
ORDER BY Sdept, Sage DESC; | |
/* 聚集函数: | |
统计元组个数 | |
COUNT (*) | |
统计一列中值的个数 | |
COUNT ([DISTINCT|ALL] < 列名 >) DISTINC 取消重复值 | |
计算一列值的总和(此列必须为数值型) | |
SUM ([DISTINCT|ALL] < 列名 >) | |
计算一列值的平均值(此列必须为数值型) | |
AVG ([DISTINCT|ALL] < 列名 >) | |
求一列中的最大值和最小值 | |
MAX ([DISTINCT|ALL] < 列名 >) | |
MIN ([DISTINCT|ALL] < 列名 >) */ | |
SELECT COUNT(*) FROM Student; | |
SELECT COUNT(DISTINCT Sno) | |
FROM SC; | |
SELECT AVG(Grade) FROM SC | |
WHERE Cno = '1'; | |
SELECT MAX(Grade) FROM SC | |
WHERE Cno = '1'; | |
SELECT SUM(Ccredit) FROM SC, Course | |
WHERE Sno = '201215012' AND SC.Cno = Course.Cno; | |
/* GROUP BY 子句分组: | |
细化聚集函数的作用对象;也就是说 GROUP BY 是和聚集函数配套使用的 | |
如果未对查询结果分组,聚集函数将作用于整个查询结果 | |
* 对查询结果分组后,聚集函数将分别作用于每个组 * | |
按指定的一列或多列值分组,值相等的为一组 */ | |
SELECT Cno, COUNT(Sno) FROM SC | |
GROUP BY Cno; | |
/* HAVING 短语与 WHERE 子句的 区别: | |
作用对象不同 | |
WHERE 子句作用于基表或视图,从中选择满足条件的元组 | |
HAVING 短语作用于组,从中选择满足条件的组。*/ | |
SELECT Sno FROM SC | |
GROUP BY Sno | |
HAVING COUNT(*) > 3; | |
SELECT Sno, AVG(Grade) FROM SC | |
GROUP BY Sno | |
HAVING AVG(Grade) >= 90; /* 查询平均成绩大于等于 90 分的学生学号和平均成绩 */ |
# 连接查询
- 连接要知道
- 连接操作不用看,知道有这么回事就行
[<表名1>.]<列名1><比较运算符>[<表名2>.]<列名2>
若在等值连接中把目标列中重复的属性列去掉则为自然连接。
/* [例 3.49] 查询每个学生及其选修课程的情况 */ | |
SELECT Student.*, SC.* FROM Student, SC | |
WHERE Student.Sno = SC.Sno; | |
/* 对上例使用自然连接 */ | |
SELECT Student.Sno,Sname,Ssex,Sage,Sd ept,Cno,Grade FROM Student,SC | |
WHERE Student.Sno = SC.Sno; | |
/*WHERE 子句由连接谓词和选择谓词组成 */ | |
SELECT Student.Sno, Sname | |
FROM Student, SC | |
WHERE Student.Sno = SC.Sno AND SC.Cno='2' AND SC.Grade > 90; | |
SELECT FIRST.Cno, SECOND.Cpno FROM Course FIRST, Course SECOND | |
WHERE FIRST.Cpno = SECOND.Cno; | |
/* 自身连接:查询每一门课的间接先修课(即先修课的 先修课)*/ | |
SELECT FIRST.Cno, SECOND.Cpno | |
FROM Course FIRST, Course SECOND | |
WHERE FIRST.Cpno = SECOND.Cno; | |
/* [例 3.53] 改写 [例 3.49] | |
左外连接:列出左表中所有的元组 */ | |
SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade | |
FROM Student | |
LEFT OUT JOIN SC ON (Student.Sno=SC.Sno); | |
/* [例 3.54] 查询每个学生的学号、姓名、选修 的课程名及成绩 */ | |
SELECT Student.Sno, Sname, Cname, Grade | |
FROM Student, SC, Course /* 多表连接 */ | |
WHERE Student.Sno = SC.Sno | |
AND SC.Cno = Course.Cno; |
# 嵌套查询
上层的查询块称为外层查询或父查询,下层查询块称为内层查询或子查询。
SQL 语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。
子查询的限制:* 不能使用
ORDER BY
子句 *。有些嵌套查询可以用连接运算替代,谨慎使用嵌套查询。嵌套的部分不做要求
但是考试写嵌套没有问题
带谓词的子查询看一看就行
用聚集函数实现子查询通常比直接用 ANY 或 ALL 查询效率要高
# [例 3.55] 查询与 “刘晨” 在同一个系学习的学生。 | |
# 不相关子查询:子查询的查询条件不依赖于父查询 | |
SELECT Sno, Sname, Sdept | |
FROM Student | |
WHERE Sdept IN ( | |
SELECT Sdept | |
FROM Student | |
WHERE Sname = '刘晨' | |
); | |
# 在 [例 3.55] 中,由于一个学生只可能在一个系学习,则 可以用 = 代替 IN: | |
SELECT Sno, Sname, Sdept | |
FROM Student | |
WHERE Sdept = ( | |
SELECT Sdept | |
FROM Student | |
WHERE Sname = '刘晨' | |
); | |
# 上例的解法 2 | |
SELECT S1.Sno, S1.Sname, S1.Sdept | |
FROM Student S1, Student S2 | |
WHERE S1.Sdept = S2.Sdept AND S2.Sname = '刘晨'; | |
# 自身链接 | |
SELECT S1.Sno, S1.Sname, S1.Sdept | |
FROM Student S1, | |
Student S2 | |
WHERE S1.Sdept = S2.Sdept | |
AND S2.Sname = '刘晨'; | |
# [例 3.56] 查询选修了课程名为 “信息系统” 的学生学号和姓名 | |
SELECT Sno, Sname | |
FROM Student | |
WHERE Sno IN ( | |
SELECT Sno | |
FROM SC | |
WHERE Cno IN ( | |
SELECT Cno | |
FROM Course | |
WHERE Cname = '信息系统' | |
) | |
); | |
# 用连接查询实现 [例 3.56] | |
SELECT Sno, Sname | |
FROM Student, | |
SC, | |
Course | |
WHERE Student.Sno = SC.Sno | |
AND SC.Cno = Course.Cno | |
AND Course.Cname = '信息系统'; | |
# [例 3.57] 找出每个学生超过他选修课程平均成绩的课程号。 | |
# 相关子查询:子查询依赖于父查询(与父查询相关),需要反复求值 | |
SELECT Sno, Cno | |
FROM SC x | |
WHERE Grade >= (SELECT AVG(Grade) | |
FROM SC y | |
WHERE y.Sno = x.Sno); | |
# [例 3.58] 查询非计算机科学系中比 计算机科学系任意一个学生年龄小的学生姓名和年龄 | |
# 带有 ANY 或 ALL 谓词的子查询 | |
SELECT Sname, Sage | |
FROM Student | |
WHERE Sage < ANY (SELECT Sage | |
FROM Student | |
WHERE Sdept = ' CS ') | |
AND Sdept <> 'CS'; | |
# 用聚集函数实现 [例 3.58] | |
SELECT Sname, Sage | |
FROM Student | |
WHERE Sage < | |
(SELECT MAX(Sage) | |
FROM Student | |
WHERE Sdept = 'CS ') | |
AND Sdept <> 'CS'; | |
# [例 3.59] 查询非计算机科学系 中比计算机科学系所有学生年龄都小的学生姓名及年龄。 | |
# 方法一:用 ALL 谓词 | |
SELECT Sname, Sage | |
FROM Student | |
WHERE Sage < ALL | |
(SELECT Sage | |
FROM Student | |
WHERE Sdept = 'CS') | |
AND Sdept <> 'CS'; | |
# 方法二:用聚集函数 | |
SELECT Sname, Sage | |
FROM Student | |
WHERE Sage < | |
(SELECT MIN(Sage) | |
FROM Student | |
WHERE Sdept = 'CS') | |
AND Sdept <> 'CS'; | |
# [例 3.60] 查询所有选修了 1 号课程的学生姓名。 | |
# 带有 EXIST 谓词的子查询不返回任何数据,只产生逻辑真值 “true” 或逻辑假植 “false” | |
SELECT Sname | |
FROM Student | |
WHERE EXISTS( | |
SELECT * | |
FROM SC | |
WHERE Sno = Student.Sno AND Cno = '1'); | |
# [例 3.61] 查询没有选修 1 号课程的学生姓名。 | |
SELECT Sname | |
FROM Student | |
WHERE NOT EXISTS( | |
SELECT * | |
FROM SC | |
WHERE Sno = Student.Sno | |
AND Cno = '1' | |
); | |
# [例 3.55] 查询与 “刘晨” 在同一 个系学习的学生。 | |
SELECT Sno, Sname, Sdept | |
FROM Student S1 | |
WHERE EXISTS( | |
SELECT * | |
FROM Student S2 | |
WHERE S2.Sdept = S1.Sdept | |
AND S2.Sname = '刘晨' | |
); | |
# [例 3.62] 查询选修了全部课程的学生姓名。 | |
# 存在量词表示全称量词 | |
# 即,不存在没有修过的课程 | |
SELECT Sname | |
FROM Student | |
WHERE NOT EXISTS( | |
SELECT * | |
FROM Course | |
WHERE NOT EXISTS( | |
SELECT * | |
FROM SC | |
WHERE Sno = Student.Sno | |
AND Cno = Course.Cno | |
) | |
); | |
# [例 3.62] 改 | |
SELECT Sname | |
FROM student | |
WHERE Sno IN ( | |
SELECT Sno | |
FROM SC | |
Group by Sno | |
HAVING count(*) = (SELECT count(*) FROM course) | |
); | |
# [例 3.63] 查询至少选修了学生 201215122 选修的全部课程的学生号码。 | |
# 不存在这样的课程 y,学生 201215122 选修了 y,而学生 x 没有选。 | |
SELECT DISTINCT Sno | |
FROM SC SCX | |
WHERE NOT EXISTS( # 学生 201215122 选修了而学生 x 没有选的课程 | |
SELECT * | |
FROM SC SCY | |
WHERE SCY.Sno = '201215122' AND NOT EXISTS( | |
SELECT * # 学生 x 选修的课程 y | |
FROM SC SCZ | |
WHERE SCZ.Sno = SCX.Sno | |
AND SCZ.Cno = SCY.Cno | |
) | |
); |
# 集合操作
并操作 UNION
交操作 INTERSECT
差操作 EXCEPTUNION:将多个查询结果合并起来时,系统自动去掉重复元组
UNION ALL:将多个查询结果合并起来时,保留重复元组
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618165334974.png" alt="image-20220618165334974" />
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618165345254.png" alt="image-20220618165345254" />
# 基于派生表的查询
通过 FROM 子句生成派生标的时候,AS 关键字可以省略,派生关系必须指定一个别名
SELECT Sno, Cno | |
FROM SC, (SELECT Sno, Avg(Grade) FROM SC GROUP BY Sno) | |
AS Avg_sc(avg_sno, avg_grade) | |
WHERE SC.Sno = Avg_sc.avg_sno AND SC.Grade >= Avg_sc.avg_grade; | |
SELECT Sname | |
FROM Student, (SELECT Sno FROM SC WHERE Cno='1') AS SC1 | |
WHERE Student.Sno=SC1.Sno |
# 3.5 数据更新
- 插入和修改和删除
INSERT | |
INTO <表名> [(<属性列1>[,<属性列2 >…)] | |
VALUES (<常量1> [,<常量2>]… ); | |
UPDATE <表名> | |
SET <列名>=<表达式>[,<列名>=<表达式>]… | |
[WHERE <条件>]; | |
DELETE | |
FROM <表名> | |
[WHERE <条件>]; |
INSERT | |
INTO Student(Sno, Cno) | |
VALUES ('201215128', '1'); | |
INSERT | |
INTO Dept_age(Sdept, Avg_age) | |
SELECT Sdept, AVG(Sage) | |
FROM Student | |
GROUP BY Sdept; | |
UPDATE Student | |
SET Sage = 22 | |
WHERE Sno = '211250106' | |
DELETE | |
From Student | |
WHERE Sno = '211250106' |
# 3.6 空值的处理(重要)
- 空值就是 “不知道” 或 “不存在” 或 “无意义” 的值。
- 一般有以下几种情况:
- 该属性应该有一个值,但目前不知道它的具体值
该属性不应该有值
由于某种原因不便于填写,或还没有赋值
- 该属性应该有一个值,但目前不知道它的具体值
判断空值用 IS NULL
或 IS NOT NULL
。
有 NOT NULL
限制的 UNIQUE
属性不能为空值,码不能为空值。
空值与其他值的算术运算结果为空值,空值与其他值的比较运算结果为 UNKNOWN
。
# [例 3.83] 选出选修 1 号课程的不及格的学生以及缺考的学生。 | |
SELECT Sno | |
FROM SC | |
WHERE Grade < 60 | |
AND Cno = '1' | |
UNION | |
SELECT Sno | |
FROM SC | |
WHERE Grade IS NULL | |
AND Cno = '1'; | |
# 或者 | |
SELECT Sno | |
FROM SC | |
WHERE Cno = '1' | |
AND (Grade < 60 OR Grade IS NULL); |
- 属性定义(或者域定义)中
- 有 NOT NULL 约束条件的不能取空值
加了 UNIQUE 限制的属性不能取空值
码属性不能取空值
- 有 NOT NULL 约束条件的不能取空值
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618165814310.png" alt="image-20220618165814310" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618165821876.png" alt="image-20220618165821876" />
# 3.7 视图
基本表定义:基本表式独立存在的表,在 SQL 中一个关系就对应一个表
视图定义:视图是由数据库中的一个表或多个表导出的虚拟表,其作用是方便用户对数据的操作。
基本表和视图的区别和联系:
视图在概念上与基本表等同,用户可以像基本表一样使用视图
只存放视图的定义,不存放视图对应的数据
基表中的数据发生变化,从视图中查询出的数据也随之改变
视图的作用
- 能够简化用户的操作(视图中数据不是直接来自基本表时,能简化)
- 能使用户以多种角度看待同一数据
- 对重构数据库提供了一定程度的逻辑独立性
- 能够对机密数据提供安全保护(每个用户只能看到他有权看到的数据)
- 适当的利用视图可以更清晰的表达查询
哪些可以更新?
行列子集视图
- 若一个视图是从单个基本表导出的,并且只是去掉了基本表的某些行和某些列,但保留了主码,我们称这类视图为行列子集视图
非行列子集视图
视图不仅可以建立在一个或多个基本表上,也可以建立在一个或多个已定义好的视图上,或建立在基本表与视图上
CREATE VIEW <视图名> [(<列名> [,<列名>]...)] | |
AS <子查询> [WITH CHECK OPTION]; | |
# WITH CKECK OPTION 表示对视图进行更新操作时要保证更新后的行满足谓词条件(即子查询中的条件,即子查询中的 WHERE) | |
# 子查询可以是任意的 SELECT 语句,是否可以含有 ORDER BY 子句和 DISTINCT 短语,则决定具体系统的实现。 | |
# [例 3.85] 建立信息系学生 的视图,并要求进行修改 和插入操作时仍需保证该 视图只有信息系的学生。 | |
CREATE VIEW IS_Student AS | |
SELECT Sno, Sname, Sage | |
FROM Student | |
WHERE Sdept = 'IS' | |
WITH CHECK OPTION; | |
# [例 3.86] 建立信息系选修了 1 号课程的学生的视图(包括学号、 姓名、成绩)。 | |
CREATE VIEW IS_S1(Sno, Sname, Grade) AS | |
SELECT Student.Sno, Sname, Grade | |
FROM Student, | |
SC | |
WHERE Sdept = 'IS' | |
AND Student.Sno = SC.Sno | |
AND SC.Cno = '1'; | |
# [例 3.87] 建立信息系选修 了 1 号课程且成绩在 90 分 以上的学生的视图。 | |
CREATE VIEW IS_S2 AS | |
SELECT Sno, Sname, Grade | |
FROM IS_S1 | |
WHERE Grade >= 90; | |
# [例 3.88] 定义一个反映学 生出生年份的视图。 | |
CREATE VIEW BT_S(Sno, Sname, Sbirth) AS | |
SELECT Sno, Sname, 2014 - Sage | |
FROM Student; | |
# [例 3.89] 将学生的学号及平 均成绩定义为一个视图 | |
CREATE VIEW S_G(Sno, Gavg) AS | |
SELECT Sno, AVG(Grade) | |
FROM SC | |
GROUP BY Sno; | |
# [例 3.90] 将 Student 表中所有女生记 录定义为一个视图 | |
# 修改基表 Student 的结构后,Student 表与 F_Student 视图 的映象关系被破坏,导致该视图不能正确工作。 | |
CREATE VIEW F_Student(F_Sno, name, sex, age, dept) AS | |
SELECT * /* 不指定属性列 */ | |
FROM Student | |
WHERE Ssex = '女'; |
DROP VIEW <视图名>[CASCADE]; | |
# [例 3.91] 删除视图 BT_S 和 IS_S1 | |
DROP VIEW BT_S; /* 成功执行 */ | |
DROP VIEW IS_S1; /* 拒绝执行 */ | |
DROP VIEW IS_S1 CASCADE; | |
# 成功执行 |
# [例 3.92] 在信息系学生的视 图中找出年龄小于 20 岁的学生。 | |
SELECT Sno, Sage | |
FROM IS_Student | |
WHERE Sage < 20; | |
# 视图消解转换后的查询语句为: | |
SELECT Sno, Sage | |
FROM Student | |
WHERE Sdept = 'IS' | |
AND Sage < 20; | |
# [例 3.93] 查询选修了 1 号课 程的信息系学生 | |
SELECT IS_Student.Sno, Sname | |
FROM IS_Student, | |
SC | |
WHERE IS_Student.Sno = SC.Sno | |
AND SC.Cno = '1'; | |
# [例 3.94] 在 S_G 视图中查询平均成 绩在 90 分以上的学生学号和平均成绩 | |
SELECT * | |
FROM S_G | |
WHERE Gavg >= 90; | |
# S_G 视图的子查询定义: | |
SELECT Sno, AVG(Grade) | |
FROM SC | |
GROUP BY Sno; | |
# 错误: | |
SELECT Sno, AVG(Grade) | |
FROM SC | |
WHERE AVG(Grade) >= 90 | |
GROUP BY Sno; | |
# 正确: | |
SELECT Sno, AVG(Grade) | |
FROM SC | |
GROUP BY Sno | |
HAVING AVG(Grade) >= 90; | |
# 或者使用派生表 | |
SELECT * | |
FROM (SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno) AS S_G(Sno, Gavg) | |
WHERE Gavg >= 90; |
# 第 4 章 数据库安全性
ppt 23-25
数据库的安全性是指保护数据库以防止不合法使用所造成的数据泄露、更改或破坏
C1 进行自主存取控制 DAC
C2 是安全产品的最低档次
B1 实施强制存取控制 MAC,是真正意义上的安全产品
存取控制(机制)
定义用户权限:用户对某一数据对象的操作权力称为权限,DBMS 提供适当的语言来定义用户权限,存放在数据字典中
合法权限检查:用户发出存取数据库操作请求,DBMS 进行合法权限检查
自主存取控制(DAC Discretionary Access ControlS)
- C2 级
- 用户对不同的数据对象有不同的存取权限
- 不同的用户对同一对象也有不同的权限
- 用户还可将其拥有的存取权限转授给其他用户
- 使用 SQL 中的
GRANT
和REVOKE
- 定义各个用户对不同数据对象的存取权限。当用户对数据库访问时首先检查用户的存取权限。防止不合法用户对数据库的存取
- 创建数据库模式的权限
- 数据库角色
- CREATE
- GRANT
- REVOKE
- 自主存取控制缺点
- 可能存在数据的 “无意泄露 “,数据本身并无安全性标记
强制存取控制 (MAC)
- B1 级,保证更高程度的安全性
- 每一个数据对象被标以一定的密级
- 每一个用户也被授予某一个级别的许可证
- 对于任意一个对象,只有具有合法许可证的用户才可以存取
- 用户不能直接感知或进行控制
- 适用于对数据有严格而固定密级分类的部门
- 军事部门
- 政府部门
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618171332380.png" alt="image-20220618171332380" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618171244565.png" alt="image-20220618171244565" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618171255039.png" alt="image-20220618171255039" />
强制存取规则为什么要这么设计,有什么内容?要知道
- 高等级才能知晓,低等级才能修改。(低级别可以通过写,来让高级别知道自己的修改)
- 避免高等级的主观失误或故意而造成的泄密。
- 并且数据无论怎么复制,密级都是固定的,一旦数据被发布,不能被修改
关注 C1\C2\A1 的对应关系
- 视图
- 把要保密的数据对无权存取这些数据的用户隐藏起来,对数据提供一定程度的安全保护
CREATE VIEW [viewname]
GRANT SELECT ON [view] to [user]
- 审计
- 启用一个专用的审计日志(Audit Log)将用户对数据库的所有操作记录在上面
- 审计员利用审计日志监控数据库中的各种行为,找出非法存取数据的人、时间和内容
- C2 以上安全级别的 DBMS 必须具有审计功能
- 审计可选
- 耗费时间和空间
- DBA 可以根据应用对安全性的要求,灵活地打开或关闭审计功能
- 用于安全性要求较高的部门
- 审计事件
- 审计功能
- AUDIT\NOAUDIT
- 数据加密
- 防止数据库中数据在存储和传输中失密的有效手段
- 根据一定的算法将原始数据明文( Plain text )变换为不可直接识别的格式 密文( Cipher text)
- 加密方法
- 存储加密
- 透明存储加密
- 非透明存储加密
- 传输加密
- 链路加密
- 端到端加密
- 存储加密
- 其他安全性保护
- 推理控制
- 隐蔽信道
- 数据隐私保护
# 第 5 章 数据库完整性
ppt 26-31
数据库的完整性是指数据的正确性和相容性。
- 完整性机制:
- (定义功能)提供定义完整性约束条件的机制
- (检查功能)提供完整性检查的方法
- (违约处理功能)
实体完整性
PRIMARY KEY
- 区分列级、表级定义
- PRIMARY KEY is UNIQUE
- PRIMARY KEY is NOT NULL
- PRIMARY KEY has INDEX
- 完整性检查和违约处理
- 全表扫描(耗时)
- 索引,如 B + 数索引
参照完整性
FOREIGN KEY [] REFERENCES []
- 违约处理
- NO ACTION: 不允许该操作执行
- CASCADE: 当删除或修改被参照表(Student)的一个元组造成了与参照表(SC)的不一致,则删除或修改参照表中的所有造成不一致的元组
- SET-NULL: 当删除或修改被参照表的一个元组时造成了不一致,则将参照表中的所有造成不一致的元组的对应属性设置为空值。
- 违约处理
用户定义完整性
CONTRAINT [约束名](随便取的名字) [约束条件]
(跟在哪个属性后面就对哪个属性生效)- NOT NULL
- UNIQUE
- CHECK (条件)
- eg:
CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%')
- 当学生的性别是男时,其名字不能以 Ms. 打头。
- eg:
- CREATE/ALTER
断言(不做要求了)
CREATE ASSERTION <断言名> <CHECK 子句>
DROP ASSERTION <断言名>
断言创建以后,任何对断言中所涉及的关系的操作都会触发关系数据库管理系统对断言的检查,任何使断言不为真值的操作都会被拒绝执行
触发器(Trigger)是用户定义在关系表上的一类由事件驱动的特殊过程
- 触发器又叫作事件 - 条件 - 动作规则。
- 触发器保存在数据库服务器中
- 任何用户对表的增、删、改操作均由服务器自动激活相应的触发器
- 触发器可以实施更为复杂的检查和操作,具有更精细和更强大的数据控制能力
- 触发器的执行,是由触发事件激活的,并由数据库服务器自动执行
- 一个数据表上可能定义了多个触发器,遵循如下的执行顺序:
- 执行该表上的 BEFORE 触发器;(谁先创建,谁先执行)
- 激活触发器的 SQL 语句;
- 执行该表上的 AFTER 触发器。
CREATE TRIGGER <触发器名> {BEFORE | AFTER} <触发事件> | |
ON <表名> REFERENCING NEW|OLD ROW AS<变量> | |
FOR EACH {ROW | STATEMENT} | |
[WHEN <触发条件>]<触发动作体> | |
#[例 5.21] 当对表 SC 的 Grade 属性进行修改时,若分数增加了 10% 则将此次操作记录到下面表中:SC_U(Sno,Cno,Oldgrade,Newgrade)其中 Oldgrade 是修改前的分数,Newgrade 是修改后的分数。 | |
CREATE TRIGGER SC_T | |
AFTER UPDATE OF Grade ON SC | |
/* 指明触发器激活的时间是在执行 UPDATE 后 */ | |
REFERENCING | |
OLD row AS OldTuple, | |
NEW row AS NewTuple | |
FOR EACH ROW /* 行级触发器 */ | |
/* FOR EACH STATEMENT 语句级触发器 */ | |
WHEN (NewTuple.Grade >= 1.1*OldTuple.Grade) | |
INSERT INTO SC_U(Sno,Cno,OldGrade,NewGrade) | |
VALUES(OldTuple.Sno,OldTuple.Cno,OldTuple.Grade,NewTuple.Grade) | |
DROP TRIGGER <触发器名> ON <表名> |
# 第 6 章 关系数据理论(必考)
ppt 32-36
# 基本概念
关系模式,是一个五元组:
R(U,D,DOM,F)
,数据依赖:是一个关系内部属性与属性之间的一种约束关系,通过属性间值的相等与否体现出来的数据间相关联系
多值依赖(Multi-Valued Dependency,MD)
函数依赖 (Functional Dependency,FD)
- Y 函数依赖于 X : X->Y ,若 X -> Y 且 Y -> X,则 X<-->Y
- Sname = f (Sno),一个学号只对应一个学生的姓名
平凡函数依赖、非平凡函数依赖 、完全函数依赖
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618173918496.png" alt="image-20220618173918496" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618173934662.png" alt="image-20220618173934662" />
码、候选码、主码、主属性、非主属性、全码(整个属性组是码)、超码
规范化 :一个低一级范式的关系模式,通过模式分解可以转换为若干个高一级范式的关系模式的集合,这种过程就叫规范化。
(此处有图 见 PDF)
# 1NF
- 第一范式 (1NF) : 作为二维表,关系要符合一个最基本的条件:每个分量必须是不可分开的数据项。(属性不可再分)
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618173620216.png" alt="image-20220618173620216" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618173628525.png" alt="image-20220618173628525" />
# 2NF
- 第二范式(2NF): 若关系模式 R∈1NF,并且每一个非主属性都完全函数依赖于任何一个候选码,则 R∈2NF。 (非主键要完全依赖候选码)
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618174429486.png" alt="image-20220618174429486" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220618174436540.png" alt="image-20220618174436540" />
实例
# 3NF
- 第三范式(3NF): 设关系模式 R<U,F>∈1NF, 若 R 中不存在这样的码 X、属性组 Y 及非主属性 Z(Z ⊈Y), 使得 X→Y,Y→Z 成立,Y ↛ X 成立,则称 R<U,F> ∈ 3NF。 (没有传递依赖)
# BCNF
- BCNF: 在关系模式 R<U,F> 中,如果每一个决定属性集都包含候选码,则 R∈BCNF
- 决定属性集:函数依赖的自变量:
- 设关系模式 R<U,F>∈1NF,若 X →Y 且 Y ⊈ X 时 X 必含有码,则 R<U,F>∈BCNF。
- 所有非主属性都完全函数依赖于每个候选码(2NF 的性质)
- 所有主属性都完全函数依赖于每个不包含它的候选码
- 没有任何属性完全函数依赖于非码的任何一组属性
- 决定属性集:函数依赖的自变量:
- 好处和消解方法见课本 P184
- 在函数依赖的范畴实现了彻底的分离,消除了插入和删除的异常
- 3NF 的不彻底性表现在可能存在主属性对码的部分依赖和传递依赖
以下内容不要求。
多值依赖:设 R (U) 是属性集 U 上的一个关系模式。X,Y,Z 是 U 的子集,并且 Z=U-X-Y。关系模式 R (U) 中多值依赖 X→→Y 成立,当且仅当对 R (U) 的任一关系 r,给定的一对 (x,z) 值,有一组 Y 的值,这组值仅仅决定于 x 值而与 z 值无关
- 对称性:若 X→→Y,则 X→→Z,其中 Z=U-X-Y
- 传递性:若 X→→Y,Y→→Z, 则 X→→Z - Y
- 经典例子:课程 C、教师 T、书 B [ Teaching(C,T,B) ]
- 一个课程多个老师,多个参考书,一个老师多个课程,一本书多个课程
- C→→T, C→→B
4NF:关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。
# 第 7 章 数据库设计
ppt 37-44
数据库设计的特点:
- 三分技术,七分管理,十二分基础数据
- 结构设计与行为设计相结合
数据库设计方法
- New Orleans 方法
- E-R 模型方法
- 3NF 方法
- OOP 方法
- UML 方法
数据库设计的基本步骤(数据库分析的 6 个阶段)
- 数据库的各级模式
- 需求分析:收集用户对数据库的信息要求、处理要求、安全性与完整性要求
- 数据字典:是关于数据库中数据的描述,即元数据,不是数据本身。包括数据项、数据结构、数据流、数据存储结构、处理过程。
- 概念结构设计:画 E-R 图(不太重要)
- E-R 图,[见 1.2](#1.2 数据模型)
- 属性必须是不可分的数据项,不能包含其他属性。
- 属性不能与其他实体具有联系,即 E-R 图中所表示的联系是实体之间的联系。
- E-R 图,[见 1.2](#1.2 数据模型)
- 逻辑结构设计:E-R 图转换为关系模型,即数据库的表
- 转换
- 一个 1:1 联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并
- 一个 1:n 联系可以转换为一个独立的关系模式,也可以与 n 端对应的关系模式合并
- 一个 m:n 联系转换为一个关系模式(本质是多对多关系需要单独开一个表来维护)
- 三个或三个以上实体间的一个多元联系转换为一个关系模式
- 具有相同码的关系模式可合并
- 设计用户子模式(视图)
- 转换
- 关系模式的分解(重要,如果问到能还原即可)
- 水平分解
- 分解后表的属性不变,但是存储的数据变了
- 把关系的元祖分为若干子集合
- 垂直分解
- 分解后表的属性变了
- 把属性分为若干子集合,形成若干子关系模式
- 水平分解
- 物理结构设计:为一个给定的逻辑数据模型选取一个最适合应用要求的物理结构
- 存取方法
- B+ Tree 索引
- hash 索引
- clustering(聚簇,这个可能没学过,要了解)
- 存取方法
- 数据库实施和维护:略
# 第 8 章 数据库编程
ppt 45-47
JDBC 比较常用,其他不考,略
过程化 sql
存储过程和函数
# 第 9 章 关系查询处理和优化
ppt 58-61
不考,略
# 第 10 章 数据库恢复技术
ppt 48-53
- 事务:是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位,是恢复和并发控制的基本单位
- 事务和程序的差别
- 在关系数据库中,一个事务可以是一条 SQL 语句,一组 SQL 语句或整个程序
- 一个程序通常包含多个事务
BEGIN TRANSACTION; # 显式开始事务
COMMIT; # 事务正常结束
ROLLBACK; # 事务回滚到开始时的状态
- 事务的特性 ACID
- 原子性(Atomicity)
- 事务是数据库的逻辑工作单位,事务中的诸操作要么都做,要么都不做
- 一致性(Consistency)
- 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态
- 全做或者全不做,数据库都处于一致性状态。
- 隔离性(Isolation)
- 一个事务的执行不能被其他事务干扰
- 一个事务内部的操作及使用的数据对其他并发事务是隔离的
- 并发执行的各个事务之间不能互相干扰
- 持续性(Durability),也称永久性(Permanence)
- 一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
- 接下来的其他操作或故障不应该对其执行结果有任何影响。
- 原子性(Atomicity)
- 故障恢复可以保证事务的原子性和持续性
- 并发控制可以保证事务的一致性和隔离性
- 数据库故障的种类
- 事物内部的故障
- 事务撤销(UNDO)
- 系统故障
- 介质故障
- 计算机病毒
- 事物内部的故障
- 恢复操作的基本原理:冗余
- 恢复的实现技术:复杂
恢复数据的原理是冗余,建立冗余数据最常用的技术是数据转储和登记日志文件
- 数据转储:数据库管理员定期地将整个数据库复制到磁带、磁盘或其他存储介质上保存起来的过程
- 备用的数据文本称为后备副本 (backup) 或后援副本
- 重装后备副本只能将数据库恢复到转储时的状态
- 静态转储
- 在系统中无运行事务时进行的转储操作
- 转储开始时数据库处于一致性状态
- 转储期间不允许对数据库的任何存取、修改活动
- 得到的一定是一个数据一致性的副本
- 优点:实现简单
- 缺点:降低了数据库的可用性
- 转储必须等待正在运行的用户事务结束
- 新的事务必须等待转储结束
- 动态转储
- 转储操作与用户事务并发进行
- 转储期间允许对数据库进行存取或修改
- 优点
- 不用等待正在运行的用户事务结束
- 不会影响新事务的运行
- 缺点
- 不能保证副本中的数据正确有效
- 利用动态转储得到的副本进行故障恢复
- 需要把动态转储期间各事务对数据库的修改活动登记下来,建立日志文件
- 后备副本加上日志文件就能把数据库恢复到某一时刻的正确状态
- 海量转储
- 每次转储全部数据库
- 增量转储
- 只转储上次转储后更新过的数据
- 海量转储和增量转储的比较
- 海量转储恢复较为方便
- 数据库很大,事务处理频繁,增量转储使用有效
日志文件:用来记录事务对数据库的更新操作的文件
格式:
- 记录
- 数据块
日志文件的内容
- 各个事务的开始标记(BEGIN TRANSACTION)
- 各个事务的结束标记(COMMIT/ROLLBACK)
- 所有更新操作
- 事务标识
- 操作类型
- 操作对象
- 更新前的值
- 更新后的值
作用:
- 事务故障恢复和系统故障恢复必须用日志文件。
- 在动态转储方式中必须建立日志文件,后备副本和日志文件结合起来才能有效地恢复数据库。
- 在静态转储方式中,也可以建立日志文件。
登记日志文件的原则
- 登记的次序严格按并发事务执行的时间次序
- 必须先写日志文件,后写数据库,为什么?(必考)(保持 ACID)
- 写数据库和写日志文件是两个不同的操作,在这两个操作之间可能发生故障。
- 如果先写了数据库修改,而在日志文件中没有登记下这个修改,则以后就无法恢复这个修改了
- 如果先写日志,但没有修改数据库,按日志文件恢复时只不过是多执行一次不必要的 UNDO 操作,并不会影响数据库的正确性
恢复策略(PPT 51)
- 事物故障:事务在运行至正常终点前被终止
- 恢复方法:由恢复子系统利用日志文件撤消( UNDO )此事务已对数据库进行的修改
- 自动完成
- 恢复步骤:反向扫描 - 逆操作 - 直至开始标记
- 系统故障:未完成事务对数据库的更新可能已写入数据库;已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库
- 恢复方法:
- UNDO 故障发生时未完成的事务
- REDO 已完成的事务
- 重启自动完成
- 恢复步骤:反向扫描,逆操作 UNDO 队列;正向扫描,执行 REDO 队列
- 恢复方法:
- 介质故障:重装数据库,重做已完成的事务
- 需要管理员介入
- 恢复步骤:装入后备数据库副本(静态 / 动态)- 装入有关日志副本,REDO 已完成的事务
- 事物故障:事务在运行至正常终点前被终止
检查点恢复技术:
为什么?
- 搜索日志和重做处理耗费了大量的时间
技术要点:
- 在日志文件中增加检查点记录
- 增加重新开始文件(新增一个记录文件)
- 恢复子系统在登录日志文件期间动态地维护日志
检查点内容:
- 建立检查点时刻所有正在执行的事务清单
- 这些事务最近一个日志记录的地址
重新开始文件的内容
- 各个检查点记录在日志文件中的地址
恢复步骤:
- 重新检查文件找到最后一条检查点记录地址,在日志文件中找到这个检查点记录
- 建立 UNDO-LIST, REDO-LIST, 将检查点上所有正在执行的事物放入 UNDO-LIST
- 从检查点记录正向扫描日志。
- 如果有新开始的事物,放入 UNDO-LIST;
- 如果有提交(COMMIT)的事物,从 UNDO-LIST 移动到 REDO-LIST。直至日志文件结束
- 对 LIST 中事物进行相应的 UNDO 和 REDO 操作
- 数据库镜像 —— 提高数据库可用性的解决方案
解决介质故障
出现故障
可由镜像磁盘继续提供使用
同时数据库管理系统自动利用镜像磁盘数据进行数据库的恢复
不需要关闭系统和重装数据库副本
没有出现故障
可用于并发操作
一个用户对数据加排他锁修改数据,其他用户可以读镜像数据库上的数据,而不必等待该用户释放锁
频繁地复制数据自然会降低系统运行效率,在实际应用中用户往往只选择对关键数据和日志文件镜像,不是对整个数据库进行镜像
# 第 11 章 并发控制
ppt 54-57
- 串行执行、交叉并发执行
- 事务是并发控制的基本单位
- 需要保证事务的隔离性和一致性
- 并发操作带来的数据不一致性
- 丢失修改:两个事务 T1 和 T2 读入同一数据并修改, T2 的提交结果破坏了 T1 提交的结果,导致 T1 的修改被丢失(造成不一致性)
- 不可重复读:不可重复读是指事务 T1 读取数据后,事务 T2 执行更新操作,使 T1 无法再现前一次读取结果。
- 3 种情况,后两种不可重复读有时也称为幻影现象(Phantom Row):
- 事务 T1 读取某一数据后,事务 T2 对其做了修改,当事务 T1 再次读该数据时,得到与前一次不同的值
- 事务 T1 按一定条件从数据库中读取了某些数据记录后,事务 T2 删除了其中部分记录,当 T1 再次按相同条件读取数据时,发现某些记录神秘地消失了。
- 事务 T1 按一定条件从数据库中读取某些数据记录后,事务 T2 插入了一些记录,当 T1 再次按相同条件读取数据时,发现多了一些记录。
- 脏读:事务 T1 修改某一数据,并将其写回磁盘。事务 T2 读取同一数据后, T1 由于某种原因被撤销。这时 T1 已修改过的数据恢复原值, T2 读到的数据就与数据库中的数据不一致。T2 读到的数据就为 “脏” 数据,即不正确的数据
- 数据不一致性:由于并发操作破坏了事务的隔离性
- 并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免造成数据的不一致性
- 关系型数据库的并发控制主要靠封锁(Locking)
封锁:
- 排它锁(X 锁、写锁),共享锁(S 锁、读锁)
- 锁的相容矩阵
- 排它锁(X 锁、写锁),共享锁(S 锁、读锁)
封锁协议
- 一级封锁协议:事务 T 在修改数据 R 之前必须先对其加 X 锁,直到事务结束才释放
- 一级封锁协议可防止丢失修改,并保证事务 T 是可恢复的。
- 如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读 “脏” 数据
- 二级封锁协议:一级封锁协议加上事务 T 在读取数据 R 之前必须先对其加 S 锁,读完后即可释放 S 锁。
- 可以防止丢失修改和读 “脏” 数据
- 因为读完数据后即可释放 S 锁,但在事务结束的时候可能其他事务已经修改了这个数据,所以它不能保证可重复读
- 三级封锁协议:一级封锁协议加上事务 T 在读取数据 R 之前必须先对其加 S 锁,直到事务结束才释放(X 和 S 锁)
- 可防止丢失修改、读脏数据和不可重复读
- 一级封锁协议:事务 T 在修改数据 R 之前必须先对其加 X 锁,直到事务结束才释放
活锁:一个事务永远可能等待,因为是新来先服务
- 解决方案:先来先服务
死锁:T1 在等待 T2 ,而 T2 又在等待 T1 , T1 和 T2 两个事务永远不能结束
预防
- 一次封锁法,要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行
- 顺序封锁法,预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁
数据库管理系统在解决死锁的问题上更普遍采用的是诊断并解除死锁的方法
解决方案
超时法:如果一个事务的等待时间超过了规定的时限,就认为发生了死锁
等待图法:发控制子系统周期性地(比如每隔数秒)生成事务等待图,检测事务。如果发现图中存在回路,则表示系统中出现了死锁。
解除死锁
- 选择一个处理死锁代价最小的事务,将其撤消
释放此事务持有的所有的锁,使其它事务能继续运行下去
- 选择一个处理死锁代价最小的事务,将其撤消
可串行化调度
- 多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行这些事务时的结果相同,这种调度策略被称为可串行化调度
冲突可串行化(掌握概念即可)
- 执行结果等价于串行调度的调度也是正确的,称为可串行化调度
- 冲突操作:是指不同的事务对同一数据的读写操作和写写操作
- 不能交换的操作:同一事务的两个操作、不同事务的冲突操作
- 一个调度 Sc 在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度 Sc’,如果 Sc’是串行的,称调度 Sc 是冲突可串行化的调度
- 冲突可串行化调度是可串行化调度的充分条件,不是必要条件
两段锁协议(2PL),指所有事务必须分两个阶段对数据项加锁和解锁
- 第一阶段:获得封锁,也称为扩展阶段。事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁
- 第二阶段:释放封锁,也称为收缩阶段。事务可以释放任何数据项上的任何类型的锁,但是不能再申请任何锁
- 事务遵守两段锁协议是可串行化调度的充分条件,而不是必要条件
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619223043853.png" alt="image-20220619223043853" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619223052600.png" alt="image-20220619223052600" />
封锁对象的大小称为封锁粒度 (Granularity)
- 逻辑单元:属性值、属性值的集合、元组、关系、索引项、整个索引、整个数据库等
- 物理单元:页(数据页或索引页)、物理记录等
封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小
多粒度封锁:在一个系统中同时支持多种封锁粒度供不同的事务选择
多粒度加锁,对一个结点加锁,意味着这个结点的所有后裔结点也被加以同样类型的锁。
- 显式封锁:直接加到数据对象上的封锁
- 隐式封锁:是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁
- 对某个数据对象加锁,系统要检查:
- 该数据对象:有无显式封锁与之冲突
- 所有上级结点:本事务的显式封锁是否与该数据对象上的隐式封锁冲突
- 所有下级结点:看它们的的显式封锁是否与本事务的隐式封锁冲突
意向锁:如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁。对任一结点加基本锁,必须先对它的上层结点加意向锁。
- IS 锁:它的后裔结点拟(意向)加 S 锁
- IX 锁:它的后裔结点拟(意向)加 X 锁
- SIX 锁:它加 S 锁,再加 IX 锁。
- e.g. 对某个表加 SIX 锁,则表示该事务要读整个表(所以要对该表加 S 锁),同时会更新个别元组(所以要对该表加 IX 锁
- 申请封锁时应该按自上而下的次序进行,释放封锁时则应该按自下而上的次序进行
# NoSQL
ppt 62-74
见《nosql 精粹》第 1-6,8-11 章
# 1. 为什么关系型数据库好 / NoSQL 和 SQL 的差异
可回答第一章的部分(关系模型的优缺点)
也可回答 PPT62 的部分
获取持久化数据
- 持久存储大量数据
集成
- 并能共享数据库集成,多个应用程序都将数据保存在同一个数据库中。这样一来,所有应用程序很容易就能使用彼此的数据了
并发
- 在面对并发操作时,关系型数据库提供了 “事务” 机制来控制对其数据的访问
- 事务在处理错误时也起到作用。比如如果事务中途出错,可以通过回滚保证数据不受破坏
近乎标准的模型
- 关系型数据库以近乎标准的方式提供了数据模型。规定了模式,具有更高的数据独立性和安全保密性。
但是存取路径对用户透明,查询效率往往不如格式化数据模型(NoSQL)
为提高性能,必须对用户的查询请求进行优化,增加了 DBMS 的难度。
NoSQL 是应用数据库,MySQL 是集成数据库
NoSQL 在集群问题上,让用户自行决定可用性和一致性的平衡
NoSQL 是无模式的,不需要预先定义值和型,不会发生阻抗失谐的问题
NoSQL
开源分布式的非关系型数据库
不使用关系模型
在集群中运行良好
- 关系型数据库使用 ACID 事务来保持整个数据库的一致性,而这种方式本身与集群环境相冲突
- NoSQL 数据库为处理并发及分布问题提供了众多选项。
开源
适用于 21 世纪的互联网公司
无模式
- 不用事先修改结构定义,即可自由添加字段了
- 这在处理不规则数据和自定义字段时 非常有用
# 2. NoSQL 的由来(考选择题)
# 阻抗失谐
关系模型和内存中的数据结构之间存在差异,存储时,需要在两种不同的表示形式之间转译。每次处理的过程很麻烦
解决方法:
- 面向对象数据库
- 对象 - 关系映射框架,通过映射模式表达转换
# 集成数据库和应用程序数据库
集成数据库和应用程序数据库的问题(NoSQL 是应用程序数据库)
# 集群问题
- 纵向扩展和横向扩展
- 分片和复制
- 让用户自行决定可用性和一致性的平衡
# 3. 聚合无知
聚合
- 把一组相互关联的对象视为一个整体单元来操作,而这个单元就叫聚合
- 键值数据库
- 文档数据库
- 列族数据库
关系型数据库不知道一个特定的聚合(数据结构),把其打散存在不同关系里,select 时,再聚在一起
- “图数据库 " 也是聚合无知的。
# 4. 无模式
关系型数据库模式和 NoSQL 模式的区别:
NoSQL 是无模式的,不需要预先定义值和型。
# 5. 分布式
概念默认大家知道,没必要考
PPT66
分片
- 不同数据存放到不同节点中
复制
- 将同一份数据拷贝到多个节点
- 主从复制
- 对等复制
# 6. 一致性和持久性
CAP 定理
- CAP 定理:给定 “一致性”(Consistency)、“可用性”(Availability)、“分区耐受性”( Partition tolerance) 这三个属性,我们只能同时满足其中两个属性。
- “一致性”
- “可用性”,如果客户可以同集群中的某个节点通信,那么该节点就必然能够处理读取及写入操作。
- “分区耐受性” ,如果发生通信故障,导致整个集群被分割成多个无法互相通信的分区时 (这种情况也叫 “ 脑裂”,split brain),集群仍然可用。
- 分区耐受性不能够妥协,但凡有一个结点 down,整个系统都要 down 掉
- CAP 定理:给定 “一致性”(Consistency)、“可用性”(Availability)、“分区耐受性”( Partition tolerance) 这三个属性,我们只能同时满足其中两个属性。
剩下的理解为主,不需要照搬背诵
# 7. 仲裁
- 经典公式:
- R + W > N
- “对等式分布模型”:
- 只有当 R+W>N 时,才能保证读取操作的 “强一致性”。其中,执行读取操作时所需联系的节点数 (R),确认写入操作时所需征询的节点数 (W),以及复制因子 (N)
- 否则,可能读到的都是 UNWRITE 的
- “主从式分布模型”
- 只需从主节点中读取数据
- “对等式分布模型”:
- 写入:二分之一
- “对等式分布模型”:
- “写入仲裁”(write quorum):如果发生两个相互冲突的写入操作,那么只有其中一个操作能为超过半数的节点所认可,W>N/2 。即,参与写入操作的节点数 (W),必须超过副本节点数 (N) 的一半。副本个数又称为 “复制因子”
- “主从式分布模型”
- 只需要向主节点中写入数据
- “对等式分布模型”:
- R + W > N
- 复制因子
- 实际情况
# 8. key-value 数据库
- 数据库是如何完成基本存放的想法 / 数据库存放的是什么东西,怎么存的
- 是一张简单的哈希表 (hash table),主要用在所有数据库访问均通过主键 (primary key) 来操作的情况下。
- 可把此表想象成传统的 “关系” 该关系有两列:ID 与 NAME
- ID 列代表关键字,NAME 列存放值。NAME 列仅能存放 String 型的数据。
- 应用程序可提供 ID 及 VALUE 值,并将这一键值对持久化
- 假如 ID 已存在,就用新值覆盖当前值,否则就新建一条数据。
- 可把此表想象成传统的 “关系” 该关系有两列:ID 与 NAME
- 客户端可以根据键查询值,设置键所对应的值,或从数据库中删除键。
- “值” 只是数据库存储的一块数据而已,它并不关心也无需知道其中的内容
- 应用程序负责理解所存数据的含义。
- 能够存储 list、set、hash 等数据结构
- 是一张简单的哈希表 (hash table),主要用在所有数据库访问均通过主键 (primary key) 来操作的情况下。
- 适合做什么,不适合做什么
- 非常适合
- 保存会话 (用会话 ID 作为键)
- 购物车数据(用 userid 绑定)
- 用户配置等信息(本质是因为键值数据库可以存放任意数据结构的数据)
- 不适合
- 数据间(建立)关系
- 含有多项操作的事务(kv 数据库不擅长回滚恢复等操作)
- 查询数据(无法搜索 value)
- 操作关键字集合(一次只能操作一个键)
- 非常适合
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619230157032.png" alt="image-20220619230157032" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619230207232.png" alt="image-20220619230207232" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619230216807.png" alt="image-20220619230216807" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619230247150.png" style="zoom:33%;" />
# 9. 文档数据库
- 数据库是如何完成基本存放的想法
- 文档彼此相似,但不必完全相同。文档数据库所存放的文档,就相当于键值数据库所存放的 “值”。
- 文档数据库可视为其值可查的键值数据库。
- 数据库存放的是什么东西,怎么存的
- “文档”(document) 是文档数据库中的主要概念。
- 其格式可以是 XML、JSON、BSON 等。
- 文档具备自述性 (self-describing),呈现分层的树状数据结构 (hierarchical tree data structure),可以包含映射表、集合和标量值。
- “文档”(document) 是文档数据库中的主要概念。
- 适合做什么,不适合做什么
- 适用:
- 事件记录(数据结构灵活)
- 内容管理系统及博客平台(数据结构灵活,支持 JSON)
- 网站分析与实时分析(可以只更新部分数据,方便保存浏览量等信息)
- 电子商务应用程序(适应较为灵活的模式)
- 不适用:
- 包含多项操作的复杂事务(不适合执行跨文档的原子操作)
- 查询持续变化的聚合结构
- 适用:
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619230532073.png" alt="image-20220619230532073" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619230539532.png" alt="image-20220619230539532" style="zoom:33%;" />
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619230738368.png" alt="image-20220619230738368" style="zoom:33%;" />
# 10. 列族数据库
- 数据库是如何完成基本存放的想法
- 列族数据库,可以存储关键字及其映射值,并且可以把值分成多个列族,让每个列族代表一张数据映射表 (map of data)。
- 列族数据库将数据存储在列族中,而列族里的行则把许多列数据与本行的 “行键”(row key) 关联起来。
- 数据库存放的是什么东西,怎么存的
- 基本存储单元为 “列”,列由一个 **“名值对 **”(name-value pair) 组成,其中的名字也充当关键字。
- 每个键值对都占据一列,并且都存有一个 “时间戳” 值。令数据过期、解决写入冲突、处理陈旧数据等操作都会用到时间戳。若某列数据不再使用,则数据库可于稍后的 “压缩阶段”(compaction phase) 回收其所占空间。
- 行是列的集合,这些列都附在某个关键字名下,或与之相连。由相似行所构成的集合就是列族。
- 每个列族都可以与关系型数据库的 “行容器”(container of rows) 相对照:
- 两者都用关键字标识行,并且每一行都由多个列组成。
- 其差别在于,列族数据库的各行不一定要具备完全相同的列,并且可以随意向其中某行加入一列,而不用把它添加到其他行中。
“标准列族”(standard column family) 中的列都是 “简单列”(simple column) 。
“超列族”(super column family):
- 如果某列中包含一个由小列组成的映射表,那么它就是 “超列”(super column)。可将超列视为 “列容器”(container of columns)。
- 用超列构建的列族叫做 “超列族” 。
- 超列族适合将相关数据存在一起。但是,如果部分列在大部分情况下都用不到,则存在不必要的开销。
“键空间” (keyspace) 与关系型数据库中的 “数据库” 类似,与应用程序有关的全部列族都存放于此。
- 必须先创建键空间,才能为其增添列族
适合做什么,不适合做什么
- 适合:事件记录、内容管理系统与博客平台、计数器、限期(利用时间戳 TTL)
- 不适合:
- 需要以 “ACID 事务” 执行写入及读取操作的系统。
- 根据查询结果聚合数据(需要把每一行读到客户端,成本高)
- 开发早期或试探某个技术方案(改变查询模式成本高)
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231049580.png" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231100397.png" alt="image-20220619231100397" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231109051.png" alt="image-20220619231109051" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231042459.png" alt="image-20220619231042459" style="zoom:33%;" />
# 11. 图数据库
- 数据库是如何完成基本存放的想法
- 图数据库可存放实体及实体间关系。
- 用图将数据一次性组织好,稍后便可根据 “关系” 以不同方式解读它。
- 数据库存放的是什么东西,怎么存的
- 实体也叫 **“节点”(node),它们具有属性 **(property)。可将节点视为应用程序中某对象的实例。
- 关系又叫 **“边”(edge),它们也有属性 **,有类型。边具备方向性 (directional significance),而节点则按关系组织起来,以便在其中查找所需模式。
- 实体和实体间关系组成的有向图(实体作为结点,实体间关系作为边)
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231153740.png" alt="image-20220619231153740" style="zoom: 45%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231212492.png" alt="image-20220619231212492" style="zoom: 45%;" />
- 适合做什么,不适合做什么
- 适合:
- 互联数据
- 安排运输路线
- 分派货物和基于位置的服务
- 推荐引擎(结点间关系)
- 不适合:
- 更新全部或某子集内的实体(无法一次改变所有结点的某个属性)
- 图数据库可能没有办法处理数据量过大的场合,即便模型适合
- 适合:
<img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231334636.png" alt="image-20220619231334636" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231341134.png" alt="image-20220619231341134" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231350216.png" alt="image-20220619231350216" style="zoom:33%;" /><img src="https://peng-img.oss-cn-shanghai.aliyuncs.com/markdown-img/image-20220619231356558.png" alt="image-20220619231356558" style="zoom:33%;" />
# 12. 4 种数据库大汇总
# 提到的可能考点
- 综合题
- 写 sql
- 写关系代数
- 写 E-R
- 简答题(几分就是几点)
- NoSQL 和 SQL 的最大差异