目录
一.绪论
一.数据库系统概述
二.数据模型
三.数据库系统的结构
四.数据库系统的组成
二.关系数据库
一.关系数据结构及形式化定义
二.关系操作
三.关系的完整性
四.关系代数
三.SQL语言
一.数据定义
二.数据查询
三.数据更新
四.视图
四.数据库安全性
1.不安全因素
2.数据库安全性控制
3.为什么要授权
4.如何授权:授予 GRANT
5.收回授权:收回 REVOKE
6.创建数据库模式的权限
7.数据库对象
8.视图机制
9.审计
10.数据加密
五.数据库完整性
1.数据库的完整性是指数据的正确性和相容性
2.维护完整性需要实现的功能
3.三大完整性
六.关系数据理论
1.函数依赖
2.码
3.范式
4.最小函数依赖集
5.模式分解
七.数据库设计的步骤
1.需求分析
2.概念结构设计
3.逻辑结构设计
4.物理结构设计
5.数据库实施
6.数据库运行和维护
八.数据库编程
1.嵌入式SQL与主语言之间的通信
2.嵌入式SQL与主语言通信的程序实例
十.数据库恢复技术
1、事务的概念
2、定义事务的SQL语句
3、事务的四个特性(ACID):原子性、一致性、隔离性、持续性
4、数据库系统的故障种类:
5.数据库恢复技术:
6、不同数据库系统故障下的恢复策略
7、具有检查点的恢复技术
十一.并发控制
1、并发控制:为了保证事务的隔离性和一致性,数据库管理系统需要对并发操作进行正确调度
2、并发控制的基本方法:封锁(X锁、S锁)
3.封锁协议:约定何时申请X锁/S锁、持续时间、何时释放
4.活锁和死锁
5、可串行化调度:多个事务并发执行的结果=这些事务按某种次序串行执行的结果
6、冲突可串行化调度
7、两段锁协议(2PL):所有事务必须分两个阶段对数据项加锁和解锁
1.数据(data):描述事物的符号记录称为数据
2.数据库(DB):长期存储在计算机内,有组织的,可共享的大量数据的集合
3.数据库管理系统(DBMS):位于用户和操作系统之间的一层数据管理软件
主要功能:
(1)数据定义功能,数据定义语言(DDL)
(2)数据组织,存储和管理
(3)数据操纵功能,数据操纵语言(DML)
(4)数据库的事务管理和运行管理
(5)数据库的建立和维护功能
(6)其他功能
4.数据库系统(DBS):由数据库、数据库管理系统、应用程序和数据库管理员(DBA)组成的存储、管理、处理和维护数据的系统
数据库系统的特点:
(1)数据结构化
(2)数据共享性高、冗余度低且易扩充
(3)数据独立性高(物理独立性、逻辑独立性)
(4)数据由数据库管理系统统一管理和控制
数据模型应满足三方面要求:能比较真实地模拟现实世界、容易为人所理解、便于在计算机上实现
1.概念模型
按用户观点建模,用于数据库设计,表示方法:E-R图
信息世界中的基本概念:
实体:客观存在并可相互区别的事物;
属性:实体具有的某一特性;
码:唯一标识实体的属性集;例如学号是学生的码
实体型:用实体名及其属性名集合来抽象刻画同类实体;例如学生(学号,姓名,性别);
联系:一对一、一对多、多对多
数据模型的组成要素
①数据结构(是对系统静态特性的描述)
②数据操作(是对系统动态特性的描述)
③数据的完整性约束条件(实体完整性和参照完整性)
2.逻辑模型(物理模型)
按计算机的观点建模,用于DBMS实现,包括网状模型、层次模型、关系模型
关系模型:
关系:一个关系对应通俗说的一张表
元组:表中的一行
属性:表中的一列
码:表中的某个属性组,可以唯一确定一个元组
域:一组具有相同数据类型的值的集合
分量:元组中的一个属性值
关系的完整性约束条件:实体完整性、参照完整性、用户定义的完整性
关系模型的优缺点:
①建立在严格的数学概念的基础上的
②关系模型的概念单一
③关系模型的存取路径对用户透明
模式:也称逻辑模式,一个数据库只有一个模式;
外模式:也称子模式或用户模式,外模式通常是模式的子集,一个数据库可以有多个外模式,外模式是保证数据库安全性的有力措施;
内模式:也称存储模式,一个数据库只有一个内模式。
数据库的二级映像功能与数据独立性
外模式/模式映像:当模式改变时,由数据库管理员对各个外模式/模式映像作相应改变,可以使外模式保持不变。应用程序是根据数据的外模式编写的,从而应用程序不必修改,保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。
模式/内模式映像:模式/内模式映像是唯一的,当数据库的存储结构改变时,由数据库管理员对模式/内模式映像作相应改变,可以使模式保持不变,从而应用程序也不必改变。保证了数据与程序的物理独立性,简称数据的物理独立性。
1.硬件平台及数据库要求:
①要有足够大的内存;
②有足够大的磁盘;
③要求系统有较高的通道能力。
2.数据库管理员职责:
①决定数据库中的信息内容和结构;
②决定数据库的存储结构和存取策略;
③定义数据的安全性要求和完整性约束条件;
④监控数据库的使用和运行;
⑤数据库的改进和重组、重构。
1.域:一组具有相同数据类型的值的集合
2.笛卡尔积:使域上的一种集合运算;R×S:由R中的每个元组与S中的每个元组进行组合。
3.关系:笛卡尔积的子集叫做关系;
候选码:关系中的某一属性组的值能唯一地标识一个元组,而其子集不能。
主码:若一个关系有多个候选码,选定一个为主码。
主属性:候选码的诸属性。
非主属性/非码属性:不包含在任何候选码中的属性。
关系可以有三种类型:基本关系(基本表)、查询表、视图表
关系模型中常用的关系操作包括:查询、插入、删除、修改;
其中查询操作的基本操作:选择、投影、并、差、笛卡尔积;
关系操作的特点是:集合操作方式,也称为一次一集合
SQL语言是一种高度非过程化的语言。
1.实体完整性:若属性A是基本关系R的主属性,则A不能取空值。
2.参照完整性:若属性F是基本关系R的外码,它与基本关系S的主码Ks相对应,则对于R中的每个元组在F的值必须:或者取空值,或者等于S中某个元组的主码值。
3.用户定义的完整性:针对某一具体关系数据库的约束条件,反映某一具体应用所涉及的数据必须满足的语义要求。
1.传统的集合运算
并:R并S,即由属于R或S的元组构成,同时去掉重复的元组
差:R差S,即由属于R但不属于S的元组构成
交:R交S,即由既属于R又属于S的元组构成
笛卡尔积:即由R中的每个元组与S中的所有元组进行组合
2.专门的关系运算
①选择 :得到表中的指定行
②投影Π:得到表中的指定列,投影后要去除重复行
③连接:将两个表根据指定条件连接在一起
等值连接是指条件为属性R.A=S.B
自然连接是指条件为属性R.A=S.A,并且要去掉重复列,写作R S
悬浮元组是指自然连接时由于S中不匹配而在R中被舍弃的元组
外连接是指保留悬浮元组的连接,不匹配的位置填NULL
左外连接是指只保留R中悬浮元组的连接,写作 ⋊
右外连接是指只保留S中悬浮元组的连接,写作 ⋉
④除÷:设R和S除运算的结果为T,则T包含所有在R中但不在S中的属性和值,且T的元组与S的元组经过组合均能出现在R中
例1:R:
A | B | C |
a1 | b1 | c2 |
a2 | b3 | c7 |
a3 | b4 | c6 |
a1 | b2 | c3 |
a4 | b6 | c6 |
a2 | b2 | c3 |
a1 | b2 | c1 |
S:
B | C | D |
b1 | c2 | d1 |
b2 | c1 | d1 |
b2 | c3 | d2 |
求R÷S:
A={a1,a2,a3,a4}
BA=a1={(b1,c2),(b2,c3),(b2,c1)}
BA=a2={(b3,c7),(b2,c3)}
BA=a3={(b4,c6)}
BA=a4={(b6,c6)}
ΠB={(b1,c2),(b2,c3),(b2,c1)}=a1;
故R÷S={a1}.
例2:
A中包含属性x和y,B中包含属性y,且B中属性y的值为全集且无重复,求全部 y的x:
例3:
1.模式
定义模式
CREATE SCHEMA<模式名> AUTHORIZATION<用户名>
删除模式
DROP SCHEMA <模式名>CASCADE; //级联:把该模式下的表、视图一起删除
DROP SCHEMA <模式名>RESTRICT; //限制:若该模式下已定义了表或视图,拒绝执行删除语句
2.基本表
(1)定义基本表
CREATE TABLE 表名
(列名1 数据类型 列级完整性约束条件,
列名n 数据类型 列级完整性约束条件,
表级完整性约束条件1,
表级完整性约束条件n
);
数据类型:
列级完整性约束条件:
表级完整性约束条件:
例:
CREATE TABLE TAB1
( Sno VARCHAR(10),
Cno NUMBER(10),
Grade INT NOT NULL,
PRIMARY KEY(Sno, Cno),
FOREIGN KEY(Sno) REFERENCES TAB2(Sno)
);
(2)修改基本表
(3)删除基本表
3.索引
数据查询是数据库的核心操作,SELECT语句具有灵活的使用方式和丰富的功能。
一般格式:
SELECT DISTINCT/ALL 目标列表达式
FROM 表名/视图名
WHERE 条件表达式
GROUP BY 列名 HAVING 条件表达式 //查询结果分组
ORDER BY 列名 次序 //查询结果排序
1.基本查询
(1)查询指定列
SELECT 列1,列n
例:查询TAB表的X,Y列:
SELECT X,Y
FROM TAB;
(2)查询全部列
SELECT *
(3)查询计算后的值
SELECT 表达式(算术表达式/字符串常量/函数)
例:查询TAB表(假设有一项属性age记录年龄)中人们的出生日期;
SELECT 2023-age
FROM TAB;
(4)改变查询结果的列标题
SELECT 列名 别名
例:查询TAB表中的X,Y列,并在结果中用别名x1,y1表示;
SELECT X x1,Y y1
FROM TAB;
(5)取消查询结果中的重复列
SELECT DISTINCT 列名
(6)聚集函数
PS:当聚集函数遇到空值,都跳过空值,只处理非空值。
聚集函数只用于SELECT语句和GROUP BY后的HAVING 子句
①统计元组个数
COUNT (*)
例:查询SC表中学生总数;
SELECT COUNT(*)
FROM SC;
②统计某一列值的个数
COUNT (DISTINCT/ALL 列名)
③计算某一列值的平均数(该列必须为数值型)
AVG(DISTINCT/ALL 列名)
例:计算SC表中的平均成绩(Grade)
SELECT AVG(Grade)
FROM SC;
④计算某一列值的总和
SUM(DISTINCT/ALL 列名)
⑤计算某一列值的最大值/最小值
MAX/MIN(DISTINCT/ALL 列名)
(7)WHERE表达式
①比较大小
例:查询TAB表中X>20的Y;
SELECT Y
FROM TAB
WHERE X>20;
②确定范围
WHERE 列名 BETWEEN 最小值 AND 最大值
WHERE 列名 NOT BETWEEN 最小值 AND 最大值
③确定集合
WHERE 列名 IN (列名1,列名n)
WHERE 列名 NOT IN (列名1,列名n)
④字符匹配
例:在Student表中查询所有姓郭且名字为三个字的学生的Sname,Sno,Sex
SELECT Sname,Sno,Sex
FROM Student
WHERE Sname LIKE ‘郭_ _ _ _’;
例:在Student表中查询所有不姓郭的学生的Sname
SELECT Sname
FROM Student
WHERE Sname NOT LIKE ‘郭%’;
⑤空值查询
WHERE 列名 IS NULL
WHERE 列名 IS NOT NULL
⑥多重条件查询
(8)GROUP BY 列名 HAVING 表达式
用于将查询结果按一列或多列的值分组,值相等的为一组
①GROUP BY 列名
例:求SC表中,各个课程号(Cno)下选课的学生数(Sno)
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno //对每一组Cno相等的元组进行count(Sno)统计人数
②GROUP BY 列名 HAVING 筛选条件
HAVING 与WHERE 的区别:
HAVING 用于从组中选出符合条件的组;
WHERE 用于从基本表或视图中选出符合条件的元组;PS(WHERE不可以接聚集函数)
(9)ORDER BY 次序
①ORDER BY 列1,列n ASC
升序排列(若不指定,默认升序)
②ORDER BY 列1,列n DESC
降序排列
2.连接查询
(1)两表连接查询
WHERE 表名1.列名1 比较运算符 表名2.列名2;(当列名在参与查询的各表中唯一,可省去表名前缀)
(2)单表连接查询
(3)外连接查询
将悬浮元组保留在结果关系中,没有属性的位置填上NULL;
①左外连接
FROM 表名1 LEFT OUTER JOIN 表名2 ON (连接条件);
②右外连接
FROM 表名1 RIGHT OUTER JOIN 表名2 ON (连接条件);
(4)多表连接查询
WHERE 表名1.列名1=表名2.列名2 AND 表名2.列名2=表名3.列名3;
3.嵌套查询
查询块:SELECT-FROM-WHERE
嵌套查询:将一个查询块嵌套在另一个查询块的WHERE子句或HAVING子句
PS:子查询的SELECT语句不能使用ORDER BY
(1)IN-子查询
父查询与子查询之间用IN连接
WHERE 列名 IN (子查询);
例:查找与吴桐同一个专业的同学
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept IN
( SELECT Sdept
FROM Student
WHERE Sname = '吴桐'
);
子查询不依赖于父查询,称为不相关子查询。
(2)比较运算符-子查询
WHERE 列名 比较运算符 (子查询);
例:在SC表中,找出每个学生(Sno)超过他平均选修课程成绩(Grade)的课程号(Cno)
SELECT Sno,Cno
FROM SC x
WHERE Grade >=
( SELECT AVG(Grade)
FROM SC y
WHERE x.Sno=y.Sno
);
子查询依赖于父查询,称为相关子查询。
(3)ANY/ALL-子查询
WHERE 列名 比较运算符 ANY/ALL (子查询);
(4)EXISTS-子查询
EXISTS的子查询不返回任何数据,只返回true或false
与之相对的是NOT EXISTS
3.集合查询
(1)UNION并操作
UNION查询时自动去除重复元素,如需保留 ,使用UNION ALL
(2)INTERSECT交操作
(3)EXCEPT 差操作
1.插入数据
(1)插入元组
INSERT
INTO 表名(列名1,列名n)
VALUES(常量1,常量n);
(2)插入子查询结果
INSERT
INTO 表名(属性列1,属性列n)
子查询;
2.修改数据
UPDATE 表名
SET 列名1=表达式1,列名n=表达式n
WHERE 条件;
3.删除数据
DELETE
FROM 表名
WHERE 条件;
1.定义视图
CREATE VIEW(列名1,列名n)
AS 子查询
WITH CHECK OPTION; //若添加该句,表示对视图增删改时要满足子查询的条件表达式。
2.删除视图
DROP VIEW 视图名 CASCADE; //使用CASCADE级联删除,则把视图导出的所有视图一并删除
①非授权用户对数据库的恶意存取和破坏;
②数据库中重要数据的泄露;
③安全环境的脆弱性。
①用户身份鉴别:静态口令鉴别、动态口令鉴别、生物特征鉴别、智能卡鉴别;
②存取控制
③自主存取控制方法。
授权是指授予(GRANT)和收回(REVOKE),是数据库安全性控制中的自主存取控制方法。是为了保护数据库,防止不合法使用所造成的数据泄露、更改和破坏。
发出如下语句的可以是数据库管理员,也可以是数据库随想创建者,也可以是已经拥有该权限的用户:
GRANT 权限 ON 对象类型 对象名 TO 用户名 [WITH GRANT OPTION];
权限:查询权限SELECT ,全部操作权限:ALL PRIVILEGES
对象类型可以是TABLE 也可以是VIEW
如果没指定 WITH GRANT OPTION 子句,则获得某种权限的用户只能使用该权限,不能传播该权限。
注意:SQL不允许循环授权,即被授权者不能把权限再授回给授权者或其祖先。
REVOKE 权限 ON 对象类型 对象名 FROM 用户名 [CASCADE|RESTRICT]
CASCADE:级联回收:将用户传播出去的权限一并收回;
RESTRICT:受限回收:若用户传播过该权限,回收失败。
CREATE USER username [WITH DBA|RESOURCE|CONNECT];
DBA:可以创建用户、创建模式、创建基本表和视图等、拥有对所有数据库对象的存取权限,还可以把这些权限授予一般用户;
RESOURCE:可以创建基本表和视图,但不能创建模式和用户。数据库对象的属主可以GRANT语句把该对象的存取权限授予其他用户;
CONNECT:只能登陆数据库,根据其他用户或数据库管理员授予的权限对数据库对象进行权限范围内的操作。
创建角色:CREATE ROLE 角色名;
在一个角色中添加角色或用户:GRANT 角色 TO 某角色/某用户 [WITH GRANT OPTION];
给角色授权:GRANT 权限 ON 对象类型 对象名 TO 角色;
角色权限收回:REVOKE 权限 ON 对象类型 对象名 FROM 角色;
为不同的用户定义不同的视图,把不需要的数据隐藏,这样用户就不会误操作。
把对数据库的所有操作都记录到审计日志中,然后就可以通过日志审查这个里面是否有一些非法的行为。
通过一些加密算法,把明文变为密文。这样别人就无法查看。
正确性:符合现实世界语义;
相容性:同一对象在不同表中的数据符合逻辑。
①提供定义完整性约束条件的机制;
②提供完整性检查的方法;
③进行违约处理。
①实体完整性:主码唯一且非空
检查与违约处理:检查主码是否唯一,如果不唯一则拒绝插入或修改;检查主码各个属性是否为空,只要有一个为空就拒绝插入或修改、
②参照完整性:外码的约束
检查:对被参照表和参照表进行增删改操作时可能会破坏参照完整性,必须检查以保证两个表的相容性。
违约处理:外码约束可以在创建参照表时说明不同的违约策略:
③用户定义完整性:属性上约束条件的定义:
(1)非平凡的函数依赖:X→Y,YX;
(2)平凡的函数依赖:X→Y,YX;
(3)完全函数依赖:X→Y,并且对于X的任意真子集X‘都有X’无法推出Y,记作XY;
(4)部分函数依赖:Y不完全函数依赖于X,记作XY。例如A→C,又有AB→C,那么C就是部分函数依赖于AB的,这种情况会造成数据冗余。
(1)候选码:一个属性组,通过该属性组能推出所有的属性,并且该属性组的任意子集都不能推出所有属性,即满足完全函数依赖,且是最小的属性组。
求所有候选码的方法:
Step1:找出一定属于候选码的属性,可能属于候选码的属性,以及不属于候选码的属性。
PS:一定属于候选码的属性:只出现在左边,或者左右都没出现;
可能属于候选码的属性:左右都出现;
不属于候选码的属性:只出现在右边。
Step2:先对确定的属性求闭包,若不能构成候选码,再将确定的属性和待定的属性进行组合,做闭包运算,直到得到的属性组能推出全部的属性。
PS:
例:集合U={A,B,C,D,E,G},函数依赖集F={AB->C,CD->E,E->A,A->G}。
Step1:一定属于候选码:B,D
可能属于候选码:A,C,E;
不属于候选码:G。
(2)超码:能推出所有属性的属性组的集合,候选码是极小的超码集,是超码的子集。
(3)主码:当有多个候选码时,挑出一个作为主码,简称码。
(4)主属性:包含在任何一个候选码中的属性。
(5)非主属性:不包含在任何一个候选码中的属性。
(6)外码:关系模式R中,若有一个属性或属性组X,它不是R的码,但X是理你给一个关系模式S中的码,称X是R的外码。
(7)全码:最极端情况下,整个属性组都是主码,称为全码。
(1)1NF:所有属性都是不可分割的数据项。
(2)2NF:在满足1NF的前提下,不包含非主属性对码的部分函数依赖(即每个非主属性都完全函数依赖于主码)。
(3)3NF:在满足2NF的前提下,不包含非主属性对码的传递函数依赖(即码应该直接决定非主属性,不能间接决定)。
(4)BCNF:消除任何属性对候选码的传递函数依赖,即每一个决定因素都包含码。
(5)4NF:不允许有非平凡且非函数依赖的多值依赖。
判断方法与分解方法:
Step1:拆分右侧
Step3:左侧最小化
1.模式分解的准则:无损连接、保持函数依赖。
2.无损连接:分解后再次自然连接,与分解前相同。
判断无损连接的方法:
Step1:画表格,列表示所有属性,有多少属性画多少列,行表示分解后的关系,有多少关系画多少行;
Step2:根据每一行关系进行判断,找到关系中每个属性对应第几列,并在相应位置上标上aj,下标j是表格里的列数,其余关系中不存在的属性则标为bij,ij对应的是表格的行列数。
Step3:依次对函数依赖集里的每个一拉关系进行考察。例如有XY->Z,在属性列中找到X和Y,观察X和Y的行列上是否有相同的标记,若有,查看他们对应在属性列Z上的各个标记,其中若有aj,则将属性列上的这些标记全部改为aj,若没有aj,则找到值最小的bij,将这些标记全部改为bij。
Step4:反复执行以上操作,直到某一行全部变为a为止,则表明具有无损连接性,否则不具有无损连接性。
调查机构情况与熟悉业务活动,明确用户需求,确定系统边界,生成数据字典和用户需求规格说明书。
将需求分析得到的用户需求抽象为概念模型,绘制E-R图。
将E-R图转换为与DBMS相符合的逻辑结构(包括数据库模式和外模式),例如E-R图向关系模式转换,再根据规范化理论对数据模型进行优化,设计用户子模式。
通常关系数据库物理设计的内容包括关系模式选择存取方法,以及设计关系,索引等数据库文件的物理存储结构。
建立实际数据库结构、试运行、装入数据。
维护数据库的安全性、完整性控制以及系统的转储和恢复;性能的监督、分析和改进;增加新功能;发现错误和修改错误。
SQL是描述性的面向集合的语句,负责操纵数据库;高级语言语句是过程性的面向记录的语句,负责控制程序流程通信。
在嵌入式SQL中,当主语言为C语言时,语法格式为EXEC SQL
当主语言为Java时,语法格式为 #SQL{
嵌入式SQL与主语言之间的通信包括:
①SQL向主语言传递执行状态信息,主要用SQL通信区实现
②主语言向SQL提供参数,主要用主变量实现
③将SQL语句查询数据库的结果交给主语言处理,主要用主变量和游标实现
SQL通信区:
SQL语句执行后的执行状态信息将送到SQL通信区中,应用程序从中取出这些信息,据此决定接下来执行的语句。SQL通信区在应用程序中用EXEC SQL INCLUDE SQLCA加以定义
主变量:
SQL语句中使用的主语言程序变量简称为主变量(即SQL使用主语言的变量)
输入主变量由应用程序赋值,SQL引用,输出主变量由SQL赋值或设置状态信息,返回应用程序
一个主变量可以附带一个任选的指示变量(整型),用来指示所指主变量的值或条件
主变量名和指示变量名前面要加冒号:作为标志
所有主变量和指示变量必须在SQL语句BEGIN DECLARE SECTION与END DECLARE SECTION 之间进行说明
游标:
SQL是面向集合的,一条SQL语句可以产生或处理多条记录,而主语言是面向记录的,一组变量依次只能存放一条记录,因此引入游标来协调这两种不同的处理方式
一个数据缓冲区,用来存放SQL语句的执行结果,每个游标区都有自己的名字
建立连接:
嵌入式SQL访问数据库必须先连接数据库
建立连接的嵌入式SQL语句为EXEC SQL CONNECT TO target[AS connection-name][USER user-name]
其中target是要连接的数据库服务器,connection-name是可选的连接名
关闭连接:
对应的嵌入式SQL语句为EXEC SQL DISCONNECT [connection]
①事务是数据库操作序列,这些操作要么全做,要么全不做,是不可分割的工作单位。一个事务可以是一个SQL语句,一组SQL语句,或者整个程序。一般来说,一个程序包含多个事务。
②事务是恢复的基本单位,也是并发控制的基本单位
开始语句:BEGIN TRANSACTION;
结束语句:COMMIT ;//表示提交事务的所有操作
或者ROLLBACK ;//表示回滚,即事务运行中发生了某种故障,需要对已完成的操作进行撤销,回滚到事务开始的状态。
①原子性:一个事务要么全做,要么全不做
②一致性:事务执行的结果必须一致。如果一个事务被迫中断,即事务的一些操作做了,剩下的还么做,且做了的对数据库造成的修改已经存入物理数据库的话,就会造成数据库处于不一致的状态。因此事务要么全做,要么全不做,一致性和原子性是密切相关的
③隔离性:一个事务的执行不能被其他事务干扰
④持续性(永久性):一个事务一旦提交,他对数据库中的数据改变应该是永久的
①事务内部的故障:事务内部的故障有的是可以通过事务本身发现的,有的是非预期的、不能由事务程序处理的
事务故障的情况下,数据库可能处于不正确的状态。恢复程序要在不影响其他事务的情况下,强行回滚该事务,即撤销该事务造成的修改,这类恢复操作称为UNDO(事务撤销)
②系统故障(软故障)
系统故障是指造成系统停止运转的任何实践,使得系统要重新启动
系统故障的情况下,在系统重启后,恢复子系统除了要撤销未完成的事务以外,还要REDO(事务重做)所有已提交的事务
③介质故障(硬故障)
外存故障,如磁盘损坏,磁头碰撞等
⑤计算机病毒
恢复机制涉及的两个关键问题:1、如何建立冗余数据;2、如何利用这些冗余数据实施数据库的恢复
恢复的基本原理:利用存储在后备副本、日志文件和数据库镜像中的冗余数据来重建数据库
建立冗余数据的技术包括:
①数据转储
数据库管理员定期将整个数据库复制到磁带、磁盘或其他存储介质上保存起来,这些备用数据称为后备副本。当数据库遭到破坏后,可将后备副本重新装入,但重装后备副本中呢个将数据库恢复到存储时的状态。要想恢复到故障发生时的状态,则必须重新运行自转储后的所有更新事务
数据转储分为:静态转储(在系统中无运行事务时进行)、动态转储(每次只转储上一次转储后更新过的数据)
数据转储也可分为:海量转储(每次转储全部数据库)、增量转储(每次只转储上一次转储后更新过的数据)
数据转储方法分为:静态海量转储、动态海量转储、静态增量转储、动态增量转储
②登记日志文件
日志文件是用来记录事务对数据库的更新操作的文件,有两种格式:以记录为单位、以数据块为单位
Ⅰ、以记录为单位的日志文件
需要登记的内容:各个事务的开始(BEGIN TRANSACTIN)标记、各个事务的结束(COMMIT/ROLLBACK)标记、各个事务的所有更新操作
日志记录的内容:事务标识、操作的类型、操作对象、更新前数据的旧值、更新后数据的新值
Ⅱ、以数据块为单位的日志文件
日志记录的内容:事务标识、被更新的数据块
日志文件的作用:
(1)事务故障恢复和系统故障恢复必须用日志文件
(2)在动态转储方式中必须建立日志文件,后备副本和日志文件结合才能有效恢复数据库
(3)在静态转储的方式中也可以建立日志文件,当数据库毁坏后可以重新装入后备副本把数据库恢复到转储结束时刻的状态,然后利用日志文件,把已完成的事务进行重做处理,对故障发生时尚未完成的事务进行撤销处理
登记日志文件的两条原则:
(1)登记的次序严格按并发事务执行的时间次序
(2)必须先写日志文件,后写数据库
①事务故障的恢复
由系统自动完成,对用户透明:利用日志文件撤销(UNDO)此事务已对数据库进行的修改
②系统故障的恢复
由系统重新启动时自动完成,不需要用户干预:撤销(UNDO)故障时未完成的事务,重做(REDO)已完成的事务
③介质故障的恢复
重装数据库,重做(REDO)已完成的事务
为避免磁盘介质出现故障影响数据库,许多数据库管理系统提供了数据库镜像功能(复制数据实现)
这种技术在日志文件中增加了检查点记录:检查点之前的事务已做完,检查点期间和之后的事务需要重做,可以改善恢复效率
并发控制的主要技术有:封锁、时间戳、乐观控制法、多版本并发控制等
并发操作带来的数据不一致性:
①丢失修改:两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失
②不可重复读:事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果
③读脏数据:事务T1修改某一数据后将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤销,这时T1修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致
①排他锁/写锁:X锁
若事务T对数据对象A加上X锁,则只允许事务T读取和修改A
事务T释放A上的X锁之前:其他事务不能读取和修改A,不能再对A加任何类型的锁
②共享锁/读锁:S锁
若事务T对数据对象A加上S锁,则事务T可以读取A,但不能修改A
事务T释放A上的S锁之前:其他事务可以读取A,可以对A加S锁,但不能修改A,也不能对A加X锁
①一级封锁协议
事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放
②二级封锁协议
事务T在修改数据R之前必须先对其加X锁(一级封锁协议),并且其他事务在读取数据之前必须先对其加S锁,读完后即可释放S锁
③三级封锁协议
事务T在修改数据R之前必须先对其加X锁(一级封锁协议),并且其他事务在读取数据之前必须先对其加S锁,直到事务结束后才释放
①活锁
事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待;T3也请求封锁R,当T1释放了R上的锁后系统首先批准了T3的请求,T2仍然等待;T4又请求封锁R,当T3释放了R上的锁后系统又批准了T4的请求........T2有可能永远等待,产生活锁
避免活锁:采用先来先服务策略
②死锁
事务T1封锁了数据R1,事务T2封锁了数据R2,T1又请求封锁R2,因T2已封锁了R2,于是T1等待T2释放R2上的锁,接着T2又申请封锁R1,因T1已封锁了R1,于是T2等待T1释放R1上的锁,这样T1在等待T2,T2又在等待T1,两个事务永远不能结束,形成死锁
解决死锁的办法:
(1)死锁的预防
Ⅰ一次封锁法:每个事务必须一次将所有要使用的数据全部加锁
Ⅱ顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务按照这个顺序实施封锁
(2)死锁的诊断与解除
诊断:Ⅰ超时法:如果一个事务等待时间超过了规定的时限,就认为发生了死锁
Ⅱ等待图法:构建事务等待图,存在回路即死锁
解除:选择一个处理死锁代价最小的事务,将其撤销(UNDO),释放此事务持有的所有锁
一个给定的并发调度,并且仅当它是可串行化的,才认为是正确调度。
例如:现有事务T1和T2,若T1与T2的并发执行结果与先T1后T2相同,或者与先T2后T1相同,那么这个调度就是正确的,否则就是错误的
冲突操作:不同事务对同一个数据的读写操作和写写操作
不同事务的冲突操作和同一事务的两个操作是不能交换的。如果调度能保证冲突操作的顺序不变,就称为冲突可串行化的调度。
①获得封锁:在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁
②释放封锁:在释放一个封锁之后,事务不在申请和获得任何其他封锁
若并发执行的所有事务均遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的。