第一章
数据库系统实现整体数据的结构化
,主要特征
之一,是db区别于文件系统
的本质区别。
数据库系统三个阶段:人工、文件、数据库系统。
数据库管理系统的功能:数据库定义、操纵 、(保护、存储、维护)、数据字典。
概念模型独立于硬件设备和DBMS
。
数据库系统的核心和基础是数据模型
和DBMS
。
数据库系统的特点:数据结构化,共享性高冗余度低易扩充,独立性高,由DBMS统一管理控制。
数据冗余问题:浪费空间/修改麻烦;数据不一致。
数据独立性高:物理、逻辑
:用户的应用程序和数据库中数据的物理存储、逻辑结构
相互独立。
数据库是长期存储在计算机内有组织、大量、共享
的数据集合。(特点)
实体、属性、码(唯一标识实体的最小属性集)、实体型(用实体名及其属性名集合表示)、实体集、联系。
数据模型应保证数据的正确、有效、相容
,任何关系必须满足实体
完整性和参照
完整性。
主要逻辑数据模型:层次模型(树)、网状模型(图)、关系模型(表):关系、元组、属性、码、域(具有相同数据类型的值的集合)、分量。
关系模型由关系数据结构、关系操作和关系完整性约束
三部分组成,完整性约束条件包括实体完整性、参照完整性、用户定义完整性
。
模式:逻辑模式,是数据库中全体数据的逻辑结构和特征的描述。是所有用户的公共数据视图。
外模式:子模式、用户模式,用户可见,一个数据库可以有多个外模式,一个应用程序只能用一个外模式。
内模式:存储模式,一个数据库只有一个内模式,是数据在数据库内部的组织方式。
外模式/模式映像:一个外模式有一个。
模式/内模式映像:只有一个。
数据库保护包括:并发控制、数据库恢复、 安全性 和 完整性。
数据库逻辑独立性
是指外模式和应用程序不变,只修改模式与外模式之间的映像,物理独立性
由管理员对模式/内模式的映像做改变。
第二章
关系代数,看看书和例题即可。
数据库基于数学上的两类运算是关系代数
和关系演算
。
视图属于概念模型
除:去重。
如果S在R中没有对应的则连接后元组数目是0,如果全都能连接数目就是15。
用二维表结构表达实体集。
选择的条件是Pcolor,一个零件只能是一个颜色,不能既是绿色又是红色,所以我们应该对表做自身连接,得到Sno相同的各种情况,选择一个为红一个为绿,即满足又有红又有绿的Sno。
第三章
sql特点:综合统一、高度非过程化
、面向集合的操作方式、以同一种语法结构提供多种使用方式、语言简洁易学易用。
0-查询篇-课程导读_哔哩哔哩_bilibili
(1)范围
①between … and … 在…之间
例:查询年龄在20岁~23岁之间的学生姓名、系别和年龄
select Sname,Sdept,Sage from Student where Sage between 20 and 30;
②not between…and… 不在…之间
例:查询年龄不在20岁~23岁之间的学生姓名、系别和年龄
select Sname,Sdept,Sage from Student where Sage not between 20 and 30;
(2) 确定集合
①in:查找属性值属于指定集合的元组(相当于数学中的属于€)
例:查询计算机科学系(CS)、数学系(MA)、信息系(IS)学生的姓名和性别
select Sname,Ssex from Student where Sdept in(‘CS’,‘MA’,‘IS’);
②not in:查找属性值不属于指定集合的元组
查询不是计算机科学系(CS)、数学系(MA)、信息系(IS)学生的姓名和性别
select Sname,Ssex from Student where Sdept not in(‘CS’,‘MA’,‘IS’);
(3)like 模糊查询
①%:表示任意长度
例:查询所有姓刘的学生的姓名、学号和性别
select Sname,Sno,Ssex from Student where Sname like ‘刘%’;
②_:表示任意单个字符
例:查询姓’欧阳’且全名为三个汉字的姓名和学号
select Sname,Sno from Student where Sname like ‘欧阳_’;
③若想查的字符本身含有_或%,则在_前加入\(空格) ‘ESCAPE’ \ '(换码字符):作用是将\后面的_ 转为普通字符,不表示通配符含义
例:查询以“DB_”开头,且倒数第三个字符为i的课程的详细情况
select * from Course where Cname like ‘DB\%i _’ ESCAPE ’ \ ';
(4)多重条件查询
①and :查询满足and两边的条件
例:查询计算机科学系年龄在20岁以下的学生姓名
select Sname from Student where sdept=‘CS’ and Sage<20;
②or:查询结果满足两边一个条件就可以
例:查询计算机科学系(CS)、数学系(MA)、信息系(IS)学生的姓名和性别
select Sname,Ssex from Student where Sdept=‘CS’ or Sdept=‘MA’ or Sdept=‘IS’;
③not:否定
(5)
①is null(null:表示不确定)
例:某些学生选修课程后没有参加考试,所以有选修记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
select Sno,Cno from SC where Grade is null;
②is not null
查询所有有成绩的学生的学号和相应的课程号。
select Sno,Cno from SC where Grade is not null;
- 3.聚集函数
(1)count(*):统计在一个关系中有多少个元组(数目)
例:查询学生总人数
select count( * )from Student
(2)count([distinct] A):计算属性A有多少个值(加[distinct]表示有多少个不同的值)
例:查询选修了课程的学生数
select count(distinct Sno) from Sc;这里的distinct表示一个人选多门课程,但是只记录1次
(3)sum([distinct] A):A的属性上所有元组加一起求和(必须为数值型)
例:查询学生201215012选修课程的总学分数
select sum(Credit) from Sc,Course where Sno=‘201215012’ and Sc.Cno=Couse.Cno;
(4)avg([distinct] A):对A的属性上所有元组求平均值(必须为数值型)
例:计算选修1号课程的学生平均成绩
select avg(grade) from Sc where Cno=‘1’;
(5)max([distinct] A):求属性A的最大值
例:查询选修1号课程的学生最高分数
select max(grade) from Sc where Cno=‘1’;
(6)min([distinct] A):求属性A的最小值
- 4.查询完整格式
select [distinct] 所查内容
from 所查询的表(可多个)
where 条件或链接或嵌套
group by 属性 对属性相同的值进行1列或多列分组
having 条件 对group by得到的组进行筛选
order by_(desc:对查询结果的一个或多个属性升序(降序排列))
例:求各个课程号及相应选课人数
select Cno,count(Sno) from Sc group by Cno;
这里的Sno用于识别是哪一门课程;group by ;分组Cno;cno组标签
例:查询平均成绩大于等于90分的学生学号和平均成绩
select sno,avg(grade) from Sc group by sno having avg(grade)>=90;
错误语句:
select sno,avg(grade) from Sc where avg(grade)>=90 group by sno;
注:where不能用聚集函数作为条件表达式的
- 5.连接查询
(1)用法:所查询信息不能在一个表中查出来,将多个表连接
(2)等值连接:运算符= ;非等值连接:其他运算符>、<…
例:查询每个学生及其选修课程的情况
select student.* ,sc.* from student,sc where student.sno=sc.sno;
(3)自然连接:在等值连接的基础上把重复属性列去掉
例:查询每个学生及其选修课程的情况
select student.sno,sname,ssex,sage,sdept,cno,grade from student,sc where studen,sno=sc.sno;
这里的Sno两个表中都有,注意区分
(4)自身连接:自己与自己做笛卡尔积,再按连接条件做选择操作
第一个表的每一行元组与第二个表的所有行元组拼接
例:查询每一门课程的间接先行课(先行课的先行课)
select first.cno,second.cpno from course first,course second where first.cpno=second.cno;
(5)外连接:悬浮元组保存在结果关系中
(6)多表连接:涉及到查询的结果在多个表中,需要将多表连接在一起
例:查询每个学生的学号、姓名、选修课程名及成绩
select Student,Sname,Cname,grade from Student,Sc,Course where Student.Sno=SC.sno and Sc.cno=Course.cno;找公共属性,sno cno将Sc表和Course表和student拼接在一起
- 6.嵌套查询
(1)分类
⑴不相关子查询:子查询的查询条件不依赖于父查询
例①:查询选修了2号课程的学生姓名
第一步找课程号为2的学生的学号,假设这里理解为一个集合它是包含课程号为2的所有学生的学号; select sno from student where cno=‘2’;然后再在这个集合里面找对应学号的学生姓名 select sname from student where sno;
这两个用IN连接,表示嵌套
select sname from student where sno IN (select sno from student where cno=‘2’);
例:②查询选修了课程名为“信息系统”的学生学号和姓名
解法1:因为信息系统课在Course表里面,而学生姓名和学号在Student表中,两者没有公共属性无法用连接查询,所以要借助SC表作为中间关系找到公共属性将两个表连接起来,这样就变为3表连接
select student.sno,sname from student,sc,course where student.sno=sc.sno and sc.cno=course.cno and course.cname=‘信息系统’;
解法2:第一步先找课程名为信息系统的课程号select cno from course where cname=‘信息系统’;其次在SC表中找选修了信息系统的学号select sno from sc where cno;这样就可以知道那各学号选修了信息系统这门课最后找学号所对应的学生姓名select sno,student from student where sno,将这3个用IN做嵌套
select sno,student from student where sno IN (select sno from sc where cno IN (select cno from course where cname=‘信息系统’));
⑵相关子查询:子查询的查询条件依赖于父查询
例:找出每个学生超过他自己选修课程平均成绩的课程号
第一步先找课程号select cno from sc x(x别名);第二步在表中查平均成绩select avg(grade) from sc y(别名)
sno:作用标注哪个学生超过他平均成绩
y.sno=x.sno相关子查询,查询的y的学号依赖于父查询x
每个学生都有自己的平均成绩,子查询要查询的平均成绩要依赖于父查询对应的哪个学生查
select sno,cno from sc x where grade>=(select avg(grade) from sc y where y.sno=x.sno);
(2)in
(3)比较运算符
(4)any,all谓词子查询
>any 大于子查询结果中某个值
>all 大于子查询结果中所有值
<>any不等于子查询结果中某个值
<>all不等于子查询结果中任何一个值
例:查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄
这里的计算机科学系是一个参照体
select sname,sage from student where sage<All (select sage from student where sdept=‘CS’) and sdept <> ‘CS’;
(5)谓词子查询
⑴exists(存在)
⑵not exists(不存在)
例:查询没有选修1号课程的学生姓名
select sname from student where not exists(select * from sc where sno=student.sno and cno=‘1’);
select * from sc where sno=student.sno and cno=‘1’;是指查询选修了1号课程的信息,而题目要求查询不是选修1号课程的信息,所以取它的补集就是没有选修1号课程的信息
*:表示查询一个表中的所有信息
- 7.集合查询
(1)intersect(交):满足两个条件
例:查询既选修了1号课程又选修了2号课程的学生。
既选1号课程又选2号课程select sno from sc where cno=‘1’; and cno=2;这是错误的,不能保证所查的属性既是1号课程又是2号课程,采用集合交,第1步找选修了1号课程select sno from sc where cno=‘1’;第2步找选修了2号课程select sno from sc where cno=‘2’;将两个条件交,度保证能够满足。
select sno from sc where cno=‘1’ INTERSECT select sno from sc where cno=‘2’;
(2)union(并):满足一个条件
例:查询选修了1号课程或者选修了2号课程的学生。
或者;采用集合并,第1步找选修了1号课程select sno from sc where cno=‘1’;第2步找选修了2号课程select sno from sc where cno=‘2’;将两个条件并,满足其中1个即可。
select sno from sc where cno=‘1’ UNION select sno from sc where cno=‘2’;
(3)except(差):
例:查询计算机科学系的学生与年龄不大于19岁的学生的差集。
直接将两个语句用EXCEPT连接
select * from student where sdept=‘CS’ EXCEPT select * from student where sage<=19;
- 8.派生表
子查询不仅可以出现在where子句中,还可以出现在from子句中,这时子查询生成临时派生表成为主查询的查询对象。
- 9.插入数据
(1)插入元组
insert into 表名(属性1,属性2…)values (‘值1’,‘值2’…)
值和属性要一 一对应
例:将一个新学生元组(学号:121200,姓名:陈东,性别:男,所在系:IS,年龄:18岁)插入student表中
insert into student(sno,sname,ssex,sdept,sage) values (‘121200’,‘陈冬’,‘男’,‘IS’,18);
若有属性,而没有对应的值要写NULL(赋空值)
(2)插入子查询结果
insert into 表名(属性1,属性2…)子查询
例:对每一个系,求学生的平均年龄,并把结果存入数据库
先建一个新表,一列存放系名,另一列存放学生平均年龄create table dept_age (sdept char(15) Avg_age SMALLINT);按系分组求平均年龄,把系名和平均年龄存入表中
insert into dept_age(sdept,Avg_age) select sdept,Avg(sage) from student group by sdept);
- 10.修改数据
(1)update 表名 set 属性(修改的值)where 条件
例:将学生201200的年龄改为22岁
update student set sage=22 where sno=‘201200’;
(2)带子查询的修改 IN
例:将计算机科学系全体学生成绩置0.
两个不同的表,先找在计算机科学系的学生学号,然后再将学号置为0
update sc set grade=0 where sno IN (select sno from student where sdept=‘CS’);
- 11.删除数据
(1)delect from 表名 where 条件
例:删除学号为201200的学生记录
delete from student where sno=‘201200’;
(2)带子查询的删除语句IN
例:删除计算机科学系所有学生的选课记录
两个不同的表,先找在计算机科学系的学生学号,然后再将选计算机科学的学号删除
delete from sc where sno IN (select sno from student where sdept=‘CS’);
四、视图
- 1.创建视图
create view 视图名(属性1,属性2)//属性可省 as 查询语句
[with check option] //可省,加上表示对视图进行插入、删除操作时要保证更新插入或删除的行满足子查询中的条件表达式
(被考到了)
例:建立信息系学生的视图
create view IS_Student AS select sno,sname,sage from student where sdept=‘IS’;
例:建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系学生
create view IS_Student AS select sno,sname,sage from student where sdept=‘IS’ with check option;
- 2.删除视图
drop view 视图名 [cascade] //[cascade] 可省,表示级联删除该视图和它导出的所有视图
例:删除视图BT_S
drop view BT_S;
- 3.查询视图
例:在信息系学生的视图中找出年龄小于20岁的学生
select sno,sage from IS_Student where Sage<20;
- 4.更新视图
例:将信息系学生视图IS_Student 中学号为“201215” 的学生姓名改为“刘辰”;
update IS_student set sname=‘刘辰’ where sno=‘201215’;
不等于所有。
第四章
B1才是真正意义上的安全产品,自主存取控制C2,强制存取控制B1。
安全性控制的一般方法有 用户身份鉴别、多层存取控制、审计、数据加密 和 视图的保护五级安全措施。
用户身份鉴别:静态口令、动态口令、生物特征、智能卡。
数据库角色是被命名的一组与数据库操作相关的权限,角色是权限的集合。
视图:
数据加密:明文->密文,存储加密、传输加密。
第五章
数据库的完整性是指数据的正确性
和相容性
。
数据库管理系统必须要实现:提供定义完整性约束条件的机制、提供完整性检查的方法、进行违约处理。
完整性:
(1)实体完整性:主码不能重复,主码不能为空。创建表时定义主键;在未设置主键的表中添加主键约束(代码p68);定义多字段联合主键;(一个表只能有一个主键)。
(2)参照完整性:外键不能为空(或者均为空值),外键等于被参照表的主码值。创建表时创建外键,添加外键;
- 破坏参照表完整性的两种下情况:在参照表中添加或修改后的元组,外码属性值在被参照表不存在;在被参照表中删除一条元组,导致相关外键值在被参照表找不到与之相等的属性值。
- 系统处理策略:拒绝执行数据操作(默认策略);级联操作(跟着变化);置空操作(不一致置空)
- 想让系统采取其他策略的sql语句p71
(3)自定义完整性:用户自己定义的完整性约束条件
Unique约束(唯一约束):指定一列或者多列里面不能出现重复值;
NOT NULL约束(空值约束)
CHECK约束(检查约束)用来限制列值的取值范围,可以结合二逻辑运算符(and in or > < =)。
完整性约束名子句 CONSTRAINT
sql学习-Constraints(约束)(primary key、 foreign key、check、default)_constraint foreign key-CSDN博客
【MySQL触发器】触发器的使用、创建、修改及删除_创建一个insert触发器-CSDN博客
第六章
非平凡的函数依赖:X → \to → Y 但 Y ⊄ \not\subset ⊂ X。
平凡的函数依赖: X → \to → Y 但 Y ⊆ X。
Y对X完全函数依赖:X → \to → Y,并对于X的任何一个真子集X‘,都有X’ ↛ \not\to → Y, X ⟶ F Y X\stackrel{F}{\longrightarrow}Y X⟶FY
Y对X部分函数依赖:X → \to → Y,但是不是完全依赖, X ⟶ P Y X\stackrel{P}{\longrightarrow}Y X⟶PY
Z对X传递函数依赖:X → \to → Y , Y ⊄ \not\subset ⊂ X,Y → \to → Z ,Z ⊄ \not\subset ⊂ Y, X ⟶ 传递 Z X\stackrel{传递}{\longrightarrow}Z X⟶传递Z。
多值依赖: X → → \to\to →→ Y,表示在关系 R 中,X 值确定的情况下,Y 的值独立于 R 中其他属性的值,具有对称性、传递性,函数依赖可以看作是多值依赖的特殊情况。
1NF:每一个分量必须是不可分的数据项。关系中的每个属性都是原子,不可再分的,每个关系都要满足1NF (平表不可嵌套)
2NF:每一个非主属性完全依赖于任何一个候选码。满足1NF且这张表中不存在属性对主键的部分函数依赖(部分函数依赖指的是依赖于主键的一部分)
3NF:满足2NF且不存在属性对主键的传递依赖。
BCNF:属性之间的函数依赖关系里面的决定值都必须为主键
4NF:还需要消除非平凡的多值依赖
无损联结性:如果一个关系模式 R(U,F) 分解为多个子关系模式 R1(U1,F1), R2(U2,F2), …, Rk(Uk,Fk),且这些子关系模式的自然连接结果与原始关系模式 R 相等,则称这种分解具有无损连接性(Lossless Join)。
重要性:无损连接性保证了分解过程中不会丢失任何数据信息。这意味着分解后的关系模式通过连接操作可以完全恢复原始关系模式的所有数据,没有信息遗失或扭曲。
判断如何判断关系模式R是否是无损连接分解 - 知乎 (zhihu.com)
依赖保持 (Dependency Preservation):若关系模式 R(U, F) 分解为 R1(U1, F1), R2(U2, F2), …, Rk(Uk, Fk),并且原始关系模式R 的每一个函数依赖要么由分解后的关系模式中的某个函数依赖集 F1, F2, …, Fk 所逻辑蕴涵,则称该分解保持函数依赖。
重要性:保持函数依赖的分解确保了原始关系中的所有数据关系和约束被维护在分解后的关系模式中。这有助于避免数据的不一致性和完整性问题。
Armstrong公理系统:
自反律(Reflexivity):如果 Y⊆X⊆U,则 X→Y 是成立的。
说明: 任何属性集总是函数决定其子集。
增广律 (Augmentation):如果 X→Y 成立,且 Z⊆U,则 XZ→YZ 也成立。
说明: 可以在函数依赖的两边同时增加相同的属性集。
传递律 (Transitivity): 如果 X→Y 和 Y→Z 成立,则 X→Z 也成立。
说明: 函数依赖具有传递性。
推论规则:
- 合并规则 (Union Rule):如果 X→Y 和 X→Z 成立,则 X→YZ 也成立。
说明: 可以合并具有相同左部的函数依赖。
- 伪传递规则 (Pseudo Transitivity Rule):如果 X→Y 和 WY→Z 成立,则 XW→Z 也成立。
说明: 当函数依赖的右部与另一个函数依赖的左部部分重叠时,可推导出新的函数依赖。
- 分解规则 (Decomposition Rule):如果 X→Y 成立,并且 Z⊆Y,则 X→Z 也成立。
说明: 函数依赖的右部可以分解成更小的部分。
重要结论
- 有效性:从F出发根据Armstrong公理系统推导出来的每一个函数依赖一定在 F + F^{+} F+中。完备性: F + F^{+} F+中的每一个函数依赖一定可以从F出发根据Armstrong公理系统推导出来。
- 函数依赖 X → A 1 , A 2 , . . . , A n X→A_1,A_2,...,A_n X→A1,A2,...,An 成立的充分必要条件是每个 X → A i X→A_i X→Ai 都成立。
- 函数依赖集 F 的闭包 F + F^+ F+ 是从 F 出发用公理导出的所有函数依赖的集合。
第七章
数据库设计的特点:三分技术、七分管理、十二分基础数据,结构(数据)设计和行为(处理)设计相结合。
数据库设计六阶段:需求分析、概念结构设计
、逻辑结构设计
、物理结构设计、数据库实施、数据库运行和维护。
概念结构设计:将需求分析得到的用户需求抽象为信息结构,是整个数据库设计的关键。
实体之间的联系:一对一、一对多、多对多。
E-R图:实体-矩形、属性-椭圆、联系-菱形,关注自我关系
。
冲突:
①属性冲突:
属性域冲突,即属性值的类型、取值范围或取值集合不同。属性取值单位冲突 。
②命名冲突:
同名异义,即不同意义的对象在不同的局部应用中具有相同的名字。
异名同义(一义多名),即同一意义的对象在不同的局部应用中具有不同的名字。
③结构冲突:
同一对象在不同应用中具有不同的抽象。
同一实体在不同子系统的E-R图中所包含的属性个数和属性排列次序不完全相同。
实体间的联系在不同的E-R图中为不同的类型。
逻辑结构设计:把概念结构设计阶段设计好的基本E-R图转换为与选用数据库管理系统产品所支持的数据模型相符合的结构。
E-R图转换关系模式:一个实体型/联系转换为一个关系模式,ER图内的实体数加多对多关系数就是关系模式里的关系数
。
第八章
SQL通信区
SQL语句执行过后,需要返回主程序若干信息,包括当前的工作状态和各种运行环境的数据等,这些信息将被送到SQL通信区中,应用程序将从SQL通信区中读取这些信息作为流程控制的依据。
SQL通信区使用
EXEC SQL INCLUDE SQLCA
加以定义,其中有一个变量sqlcode,用来存放每次执行SQL之后返回的代码。应用程序每执行一次SQL就应检查一下sqlcode的值(success,其他)
主变量
SQL语句中使用的主语言程序变量称为主变量;
分为输入主变量(主程序赋值,SQL引用)和输出主变量(SQL赋值或设置状态信息,返回给应用程序);
一个主变量可以附带一个任选的指示变量(indicator variable),为一个整数变量,用来指示其所属的主变量的值或者条件,可以检测主变量是否为空;
所有主变量必须在
begin decalre section
和end declare section
之间进行说明,说明之后,主变量就可以在SQL语句中任何可以使用表达式的地方出现,为了与数据库对象名(表名,列名等)区分,嵌入式SQL语句中的主变量和指示变量都要在前面加上冒号;
游标
SQL语言面向集合,一条SQL语句可以返回多条记录;主语言一般是面向记录的,一次只能处理一条记录;
为了协调,引入了游标的概念;
游标是系统为用户开设的一个
数据缓冲区
,存放SQL的执行结果,每一个游标区都有自己的名字,用户可以通过游标逐一获得记录并进行处理。功能:把集合记录转化为单记录。
建立和关闭数据库连接
建立数据库连接:
exec sql connect to target [AS connection-name] [USER user-name];
target:要连接的数据库服务器,可以是像@:一样的服务器表示串,还可以是DEFAULT,还可以是包含服务器标识的SQL串常量。
connection-name:可选的连接名,用来识别程序内建立的多个数据库连接,如果程序内只有一个数据库连接,也可以不指定。
关闭数据库连接:
exec sql disconnect[connection];
必须使用游标的SQL语句包括:
- 查询结果为多条记录的select语句;
使用游标机制将查询结果一条一条的送给主程序处理;
说明游标:
exec sql declare <游标名> cursor for <select 语句>;
此时并不会执行SQL语句;
打开游标:
exec sql open <游标名>;
执行相应的select语句,并将结果放置到缓冲区。推进游标指针并获取当前的记录:
exec sql fetch <游标名> into <主变量>[<指示变量>] [,<指示变量>]...;
关闭游标:
exec sql close <游标名>;
游标被关闭后就不再与原来的查询结果相关联;被关闭的游标可以被再次打开;
current
形式的update
和delete
语句;
在
update
和delete
中使用如下的子句:where current of <游标名>;
第九章
关系数据库系统查询:查询分析、查询检查、查询优化、查询执行。
查询优化
- 代数优化:是指关系代数表达式的优化,也即按照一定规则,通过对关系代数表达式进行等价变换,改变代数表达式中操作的次序和组合,使查询更高效
- 物理优化:是指存取路径和底层操作算法的选择。选择依据可以是基于规则的(rule based)、基于代价的(cost based)、基于语义的(semantic based)
查询树:从下至上:表-连接-选择-投影。
画法:数据库必考习题8-有关查询树,优化查询树的题_哔哩哔哩_bilibili
根据优化后的语法树写出关系代数:
第十章
数据库恢复技术知识点合集(复习总结)_数据库恢复技术重点-CSDN博客
事务:用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位(恢复和并发控制的基本单位
)
事务的ACID特性:
原子性:
事务是数据库的逻辑工作单位。
事务中包括的诸操作要么都做,要么都不做(简单来说就是事务是一个整体)一致性:
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态
一致性状态(数据正确的状态):在事务间没有干扰的情况下,数据库中只包含成功事务提交的结果;
不一致状态:数据库中包含未完成事务的结果。
注:一致性和原子性密切相关。原子性就说明了要么都做要么都不做,但是你只做一个操作,那这个事务就没有完成,就可能保证不了事务的一致性了。
隔离性:
一个事务的执行不能被其他事务干扰
一个事务内部的操作及使用的数据对其他并发事务是隔离的
并发执行的各个事务之间不能互相干扰持续性:
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的
即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作
事务的特性:
保证事务ACID特性是事务处理的任务。
破坏事务ACID特性的因素:(1)多个事务并行运行时,不同事务的操作交叉执行;(隔离性)
(2)事务在运行过程中被强行停止。(隔离性和原子性)
故障种类:
- 事务内部的故障
某个事务在运行过程中由于种种原因未运行至正常终止点就夭折了(非正常终止)
(1) 可预期的,可以通过事务程序本身发现,及时回滚保证数据库的一致性;
(2) 非预期的,不能由事务程序处理的,比如求阶乘,导致数据外溢。
事务故障的恢复:事务撤销(UNDO)
强行回滚该事务
撤销该事务已经做出的任何对数据库的修改,使得该事务像根本没有启动
系统故障——软故障
是指造成系统停止运转的任何事件,使得系统重新启动。影响正在运行的所有事务,但不破坏数据库;
所有正在运行的事务都非正常终止;
内存中数据库缓冲区的信息全部丢失;
部分尚未完成的事务的结果可能已送入物理数据库,从而造成数据库可能处于不正确的状态;
系统故障的原因:
特定类型的硬件错误(如CPU故障)
操作系统故障
DBMS代码错误
系统断电导致系统崩溃的计算机病毒
系统故障的恢复:
发生系统故障时,事务未提交,直接强行撤销(UNDO)所有没有完成的事务;
发生系统故障时,事务已提交,但是缓冲区的信息尚未完全写回磁盘,直接重做(REDO)所有已提交的事务
- 介质故障——硬故障
指外存故障,破坏性最大
介质故障的原因:
磁盘损坏
磁头碰撞
操作系统的某种潜在错误
瞬时强磁场干扰
破坏硬盘数据的计算机病毒
介质故障的恢复
需要借助存储在其他地方的数据备份来恢复数据库;
装入数据库发生介质故障前某个时刻的数据副本;
重做自此时始的所有成功事务,将这些事务已提交的结果重新记入数据库;
- 计算机病毒
总结:各类故障,对数据库的影响有两种可能性:
- 数据库本身被破坏:
介质故障
,计算机病毒 - 数据库没有被破坏,但数据可能不正确,这是由于事务的运行被非正常终止造成的:
事务内部故障,系统故障
,计算机病毒
恢复技术:
恢复操作的基本原理:(冗余)利用存储在系统其它地方的冗余数据来重建数据库中已被破坏或不正确的那部分数据;
数据转储:DBA将整个数据库复制到其他存储介质上保存起来的过程,备用的数据称为后备副本或后援副本。
- 静态转储
实现简单,但降低了数据库的可用性
- 得到的一定是一个数据一致性的副本
- 转储期间不允许对数据库的任何存取、修改活动
- 转储开始时数据库处于一致性状态
- 在系统中无运行事务时进行的转储操作
转储必须等待正在运行的用户事务结束,新的事物必须等转储结束!
- 动态转储
转储操作与用户事务并发进行
转储期间允许对数据库进行存取或修改(这里就能反应副本中的数据可能不正确)优点:1. 不用等待正在运行的用户事务结束 2. 不会影响新事务的运行
缺点:不能保证副本中的数据正确有效
注:利用动态转储得到的副本进行故障恢复,需要把动态转储期间各事务对数据库的修改活动登记下来,建立日志文件!!!后备副本加上日志文件才能把数据库恢复到某一时刻的正确状态。
日志文件的作用:
可用来进行事务故障恢复和系统故障恢复,并协助后备副本进行介质故障恢复。
- 事务故障恢复和系统故障恢复,必须用日志文件;
- 静态转储后的后备副本进行介质故障恢复,也可用日志文件;
- 动态转储后的后备副本进行介质故障恢复,必须用日志文件;
日志文件的检查点是各个事务的所有更新操作。
基本原则:
- 登记的次序严格按并行事务执行的时间次序
- 必须先写日志文件,后写数据库(就是说你要做操作了就先写入日志文件中,写完之后在对数据修改到数据库中)
隔离性:并发控制
原子性:安全性
一致性:完整性
第十一章
第11章 并发控制 | 数据库知识点整理 - 望三星 - 博客园 (cnblogs.com)
并发操作带来的数据不一致性包括三类:
丢失修改(LostUpdate)
两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了(覆盖了)T1提交的结果,导致T1的修改被丢失。
不可重复读(Non-RepeatableRead)
不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。
不可重复读包括三种情况:
- 事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读改数据时,得到与前一次不同的值
- 事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录消失了
- 事务T1按一条件从数据库中读取某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录后两种不可重复读有时也称为幻影(phantom row)现象
读“脏”数据(DirtyRead)
读“脏”数据是指事务T1修改某一数据,并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤销,这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致,则T2读到的数据就为“脏”数据,即不正确的数据。
避免不一致性的方法和技术就是并发控制。常用的并发控制技术包括封锁技术、时间戳方法、乐观控制方法、多版本并发控制方法
等
封锁
就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。
基本的封锁类型有两种:
- 排它锁(X锁)又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。
- 共享锁(S锁)又称为读锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
封锁协议:
- 一级封锁协议:修改前加X锁,事务结束释放。写的时候不能写
- 二级封锁协议:读数据前加S锁,读完释放。写的时候不能读
- 三级封锁协议:读数据前加S锁,事务结束释放。保证在使用期间数据不被修改。
活锁:
- 活锁产生的原因:当一系列封锁不能按照其先后顺序执行时,就可能导致一些事务无限期等待某个封锁,从而导致活锁。
- 避免活锁的简单方法是采用
先来先服务
的策略。当多个事务请求封锁同一数据对象时,封锁子系统按请求封锁的先后次序对事务排队,数据对象上的锁一旦释放就批准申请队列中第一个事务获得锁。
死锁:
在数据库中,产生死锁的原因是两个或多个事务都已封锁了一些数据对象,然后又都请求已被其他事务封锁的数据加锁,从而出现死等待。防止死锁的发生其实就是要破坏产生死锁的条件。预防死锁通常有两种方法:
- 一次封锁法(哲学家进餐)
要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。- 顺序封锁法
预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。
请给出检测死锁发生的一种方法,当发生死锁后如何解除死锁?
- 数据库系统一般采用允许死锁发生,DBMS检测到死锁后加以解除的方法。
- 超时法:如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。
- 等待图法:子系统周期性地生成事务图(有向图),若存在回路则出现死锁。
- 解除死锁:通常采用的方法是选择一个处理死锁代价最小的事务,将其撤消,释放此事务持有的所有锁,使其他事务得以继续运行下去。
可串行性
是并发事务正确调度的准则。
可串行化的调度的定义:多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同,我们称这种调度策略为可串行化的调度。
如果它们满足以下三个条件,则说两个操作存在冲突
:
- 这两项业务都属于不同的事务。
- 两个操作都在同一个数据项上运行。
- 至少有一个操作是写操作。
判断是否可串行化:原调度Sc只要交换两个事务不冲突的操作
,如果能转化为一个串行调度Sc’,那么Sc为冲突可串行化调度
,即是正确的调度。
两段锁协议是指所有事务必须分两个阶段对数据项加锁和解锁。
在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁;
在释放一个封锁之后,事务不再申请和获得任何其他封锁。
“两段”的含义是,事务分为两个阶段:
- 第一阶段是获得封锁,也称为扩展阶段。在这阶段,事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁。
- 第二阶段是释放封锁,也称为收缩阶段。在这阶段,事务释放已经获得的锁,但是不能再申请任何锁。
事务遵守两段锁协议是可串行化调度的充分条件,不是必要条件。
封锁粒度:封锁对象的大小。
为什么要引进意向锁? 意向锁的含义是什么?
-
引进意向锁是为了提高封锁子系统的效率。
-
原因是:在多粒度封锁方法中,一个数据对象可能以两种方式加锁—显式封锁和隐式封锁。因此系统在对某一数据对象加锁时不仅要检查该数据对象上有无(显式和隐式)封锁与之冲突;还要检查其所有上级结点和所有下级结点,看申请的封锁是否与这些结点上的(显式和隐式)封锁冲突;显然,这样的检查方法效率很低。为此引进了意向锁。
-
意向锁的含义是:对任一结点加锁时,必须先对它的上层结点加意向锁。引进意向锁后,系统对某一数据对象加锁时不必逐个检查与下一级结点的封锁冲突了。
-
IS锁:如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。例如,要对某个元组加S锁,则要首先对关系和数据库加IS锁
-
IX锁:如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。例如,要对某个元组加X锁,则要首先对关系和数据库加IX锁。
-
SIX锁:如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX。
主要参考:
数据库期末总结笔记( 零基础 ) - 知乎 (zhihu.com)
数据库系统概论—期末复习(超系统、详细) - 知乎 (zhihu.com)