河海大学数据库知识点归纳整理
前言
该文档主要包含了对河海大学数据库这一门课程进行的知识点归纳,并且提供了ppt等其他复习资料。
河海大学许卓明老师数据库期末考点!
1 CH01 CH02
- 数据模型与数据模式、概念数据模型与概念数据模式、数据库系统与数据库管理系统
a. 数据模型:用来描述数据的一组概念和定义。这种描述包括三个要素/两个方面:
数据的基本结构 / 静态特性:数据的逻辑/物理结构和数据间的联系。
数据中的约束 / 静态特性:语义施加在数据上的约束(称完整性约束)。
数据上的操作 / 动态特性:如何检索、更新(增、删、改)数据。
b. 数据模式:运用某种数据模型(手段)对一个企业(Enterprise)/组织(Organization)(如:公司、学校、政府部门)的一组数据之结构、联系和约束进行描述的结果(目的)。
c. 概念数据模型:面向现实世界/用户,与DBMS无关。
概念数据模式:是用逻辑数据模型对一个单位的数据的描述。概念设计是数据库设计的最基本任务。概念模式也称为逻辑模式。
d. 数据库系统:应用程序、数据库管理系统、数据库和数据库管理员构成数据库系统。
e.数据库管理系统:DBMS是数据库系统的核心,1.提供高级的用户接口 2.查询处理和优化 3.数据目录管理 4.并发控制 5.恢复功能 6.完整性约束检查 7.访问控制。
f. 多级数据模型: 概念数据模型(conceptual data model):面向现实世界/用户,与DBMS无关
e.g. E-R模型、O-O模型
逻辑数据模型(logical data model):既面向用户、又面向实现
e.g. 网状模型、层次模型、关系模型、O-O模型
物理数据模型(physical data model):面向机器世界/实现,描述数据的存储结构。与DBMS、OS、硬件有关。
2.关系代数操作
- 投影操作
选出关系r中由<属性表>所示的诸属性列值,构成一个新的关系。(纵向筛选)
∏ \prod ∏<属性表>( r ) = {t [<属性表>] | t ∈ r}
e.g. ∏ \prod ∏job, sal (emp) - 并(Union)
r∪s = { t | t ∈ r OR t ∈ s }
- 差(Difference)
r -s = {t | t ∈ r AND (t ∈ s) }
- 选择(Selection)
选出关系r中满足<选择条件>的元组,构成一个新的关系。(横向筛选)
б<选择条件>( r ) = {t | t ∈ r AND <选择条件>}
- 交(Intersection)
不是独立的操作。因为r∩s = r―(r―s)
- 笛卡尔积(Cartesian Product)
r×s = { <t, g> | t ∈ r AND g ∈ s }
序偶<t, g>称元组t与元组g的拼接(Concatenation)
r×s的目为nr+ns,元组数为|r|×|s|。
e.g. emp×dept
- 连接(Join):从两个关系 r 和 s 的所有元组拼接中选出满足<连接条件>者,构成一个新关系。
r <连接条件> s =б<连接条件> (r×s)
<连接条件>的一般形式为:C1 AND C2 AND … AND Ck
其中,Ci形式为: AiθBi, Ai, Bi分别为r, s中的属性。θ为关系运算符。
故连接也称θ连接(Theta-join)。当θ为“=”时,有两类特殊连接:
等连接(Equijoin):在连接结果中保留两关系中重复的属性列。
自然连接(Natural Join):在连接结果中只保留两关系中重复属性列中之一。
在实际中,连接常指自然连接。
2 CH03
- 基表的创建(Create Table Construct)
SC:
上:stu 下:course
实体完整性约束:PRIMARY KEY
唯一性约束:UNIQUE
非空值约束:NOT NULL
引用完整性约束:FOREIGN KEY
PK与UNIQUE的区别
一、作为Primary Key的域/域组不能为null,而Unique Key可以。
二、在一个表中只能有一个Primary Key,而多个Unique Key可以同时存在。
例1:建立一个“部门”表dept,它由部门号deptno、部门名deptname、位置loc等属性组成。其中部门号是主键,部门名取值不能为空,且唯一。
部门:dept(deptno, dname, loc)
CREATE TABLE dept
( deptno INT PRIMARY KEY,
dname VARCHAR(10) NOT NULL UNIQUE,
loc VARCHAR(10)
CHECK ( loc IN (‘Shanghai’,’Nanjing’, ‘Wuhan’,
‘Xian’, ‘Beijing’))
);
CHECK: CHECK 约束用于限制列中的值的范围。
如果对单个列定义 CHECK 约束,那么该列只允许特定的值。
如果对一个表定义 CHECK 约束,那么此约束会在特定的列中对值进行限制。
IN条件--用于属于判断:<列标识> [NOT] IN (常量1, 常量2, …, 常量n)∣(<子查询>)
- 基表模式的修改与撤销
1.增加列
ALTER TABLE <表名> [ ADD <新列名> <数据类型> [ 完整性约束 ] ];
<表名> :要修改的基本表
ADD子句:增加新列和新的完整性约束条件
[例]向emp表增加“性别”列,其数据类型为字符型。
ALTER TABLE emp ADD GENDER CHAR(2) NOT NULL;
2.删除基表
DROP TABLE <表名>;
基表删除,数据、表上的索引都删除
系统从数据字典中删去有关该基表及其索引的描述
[例]删除emp表
DROP TABLE emp ;
3.删除属性列-间接删除
把表中要保留的列及其内容复制到一个新表中
删除原表
再将新表重命名(RENAME)为原表名
4.修改属性列
ALTER TABLE <表名> MODIFY <列名> <数据类型>;
[例] 将emp表中工号改为字符类型,串长度改为8位。
ALTER TABLE emp MODIFY empno CHAR(8);
注:修改原有属性定义有可能会破坏已有数据
5.补充定义主键
ALTER TABLE <表名> ADD PRIMARY KEY(列名表);
要求定义为主键的列名表必须满足NOT NULL和唯一性条件
6.撤销主键定义
ALTER TABLE <表名> DROP PRIMARY KEY;
暂时撤销主键定义,在插入新的元组时,可以提高系统的性能
7.补充定义外键
ALTER TABLE 基表
ADD FOREIGN KEY [ 外键名 ](列名表)
REFERENCES 主表
[ON DELETE {RESTRICT | CASCADE | SET NULL}];
RESTRICT:被基表引用的主键不得删除。
CASCADE:主表中主键删除,基表中引用此主键的行也被删除。
SET NULL:该列设为NULL。
8.撤销外键定义
ALTER TABLE <基表> DROP <外键名>;
- SQL数据查询语言
背景
dept(部门) (deptno(部门号), dname(部门名称), loc(所在地))
emp(职员) (empno(工号), ename(姓名), job(职位), mgr, hiredate, sal(薪水), comm, deptno(部门号))
无条件查询
1)查询全部职员的工号与姓名。 SELECT empno, ename FROM emp;
2)查询全部部门的号码、名称、所在地。 SELECT deptno, dname, loc FROM dept;
或 SELECT * FROM dept;
3)查询职员的所有工种。
SELECT DISTINCT job FROM emp;(去除重复项)
4)查询每个职员提薪20%后的薪水。
SELECT empno, ename, sal*1.2 FROM emp;
5)查询单位的薪水种类。
SELECT [ALL] sal FROM emp;
SELECT DISTINCT sal FROM emp;
注意 DISTINCT短语的作用范围是所有目标列
例:查询所有主管经理的工号
错误的写法
SELECT DISTINCT ename, DISTINCT mgr FROM emp;
正确的写法 SELECT DISTINCT ename, mgr FROM emp;
这与SELECT ename, mgr FROM emp;
查询结果不同
比较条件查询
6) 查询所有销售人员的姓名、所在部门号。
SELECT ename, deptno FROM emp WHERE job=’salesman’;
7)查询薪水超过5000的职员。
SELECT empno, ename, sal FROM emp WHERE sal>5000;
8)查询没有佣金的职员。
SELECT empno, ename FROM emp WHERE comm IS NULL;
错误:
SELECT empno, ename FROM emp WHERE comm = NULL;
范围查询
9)查询薪水在3000与5000之间的职员。
SELECT empno, ename FROM emp WHERE sal BETWEEN 3000 AND 5000;
字符匹配查询
10) 找出姓名以M打头的所有职员。
SELECT deptno, ename FROM emp WHERE ename LIKE ‘M%’;
11)找出姓名第三个字母为r的所有职员。
SELECT deptno, ename FROM emp WHERE ename LIKE ‘_ _R%’;
12)查询DB_Design课程的课程号和学分。
SELECT CNO,CREDIT FROM Course WHERE CNAME LIKE 'DB\_Design' ESCAPE '\’;
属于判断查询
13) 找出不是经理、销售人员的所有职员的薪水。
SELECT ename, job, sal FROM emp WHERE job NOT IN ( ‘manager’, ‘salesman’ ) ;
连接查询
14)(多表连接)查询职员Allen的工作所在地。
SELECT ename, loc FROM emp, dept WHERE ename=’Allen’ AND emp.deptno = dept.deptno;
15)(单表连接)查询薪水超过其部门经理的职员、及其经理姓名。
SELECT worker.ename, manager.ename
FROM emp worker, emp manager
WHERE manager.empno = worker.mgr AND worker.sal > manager.sal;
16)(单表连接)查询薪水比Jones高的职员。
SELECT x.empno, x.ename
FROM emp x, emp y
WHERE y.ename = ‘Jones’ AND x.sal > y.sal;
存在查询
17)查询所有已雇用职员的部门。
SELECT deptno, dname FROM dept WHERE EXISTS ( SELECT * FROM emp WHERE emp.deptno = dept.deptno);
子查询 / 嵌套查询
子查询 的SELECT语句不能有ORDER BY之句;子查询可嵌套。
- 查询结果分组
18)查询与Jones相同工种的所有职员。
SELECT empno, ename FROM emp
WHERE job =(SELECT job FROM emp WHERE ename = ‘Jones’);
19)查询每个部门的薪水最大值、最小值和平均值。
SELECT deptno, MAX(sal), MIN(sal), AVG(sal)
FROM emp GROUP BY deptno;
SELECT deptno, MAX(sal), MIN(sal), AVG(sal) FROM emp;
20)查询每个部门中clerk人员的人数、平均薪水。
SELECT deptno部门号, COUNT(*), AVG(sal) FROM emp
WHERE job = ‘clerk’ GROUP BY deptno;
21)查询每个部门中salesman人员最高薪水、最低薪水,要求最高薪水、最低薪水相差超过1000。
SELECT deptno, MAX(sal), MIN(sal) FROM emp
WHERE job = ‘salesman’
GROUP BY deptno
HAVING MAX(sal)–MIN(sal) > 1000;
22)查询每个部门中每个工种有多少职员。
可能的结果是:
DEPTNO JOB COUNT(JOB)
11 clerk 2
11 manager 1
13 manager 2
13 analyst 4
13 clerk 3
12 manager 1
12 clerk 1
12 salesman 5
26) 查询每个部门中每个工种有多少职员,要求查询结果按deptno升序、job降序输出。
SELECT deptno, job, COUNT(job) FROM emp
GROUP BY deptno, job;
ORDER BY deptno, 2 DESC ;
可能的结果是:
DEPTNO JOB COUNT(JOB)
11 manager 1
11 clerk 2
12 salesman 5
12 manager 1
12 clerk 1
13 manager 2
13 clerk 3
13 analyst 4
27)列出所有老销售人员及刚刚雇用的新销售人员名单。
SELECT empno, ename FROM emp WHERE job = ‘salesman’
UNION
SELECT empno, ename FROM new-emp;
- 插入数据
28)在dept表中增加一个新部门。
INSERT INTO dept VALUES (14, ‘production’, ‘Wuhan’);
29)在emp表中增加一个新的销售员工,部门为14,部门经理为158。
INSERT INTO emp (empno, ename, job, mgr, hiredate, deptno)
VALUES (298, ‘Julian’, ‘salesman’, 158, 2006-09-01, 14);
新插入的记录在sal和comm列上取空值。
等价于:
INSERT INTO emp
VALUES (298, ‘Julian’, ‘salesman’, 158, 2006-09-01, NULL, NULL, 14);
30)(多行间接插入)将emp表中manager员工或佣金超过其工资50%的员工之相关数据拷贝到bonus表中。
INSERT INTO bonus (e-name, work, salary, comm)
SELECT ename, job, sal, comm
FROM emp WHERE job=’manager’ OR comm > 0.5*sal ;
- 修改数据
31)(全部更新) 将emp表中所有员工的佣金置为NULL。
UPDATE emp SET comm = NULL ;
32)(条件更新) 将Jones提升为14部门的经理,其薪水增加2000。
UPDATE emp
SET job=’manager’, sal=sal+2000.0, deptno=14
WHERE ename=’Jones’ ;
33)(复杂更新) 在西安或武汉的部门要撤消,其员工全部调入公司总部,职务不变,薪水和佣金分别是原部门平均值的1.1倍和1.5倍。
UPDATE emp x
SET deptno = (SELECT deptno FROM dept WHERE dname=’headquarters’) ,
(sal, comm) = (SELECT 1.1*AVG(sal), 1.5*AVG(comm) FROM emp y
WHERE y.deptno = x.deptno)
WHERE deptno IN (SELECT deptno FROM dept
WHERE loc=’Xian’ OR loc=’Wuhan’
- (全部删除) 将emp表中全部行删除。
DELETE FROM emp ;
[注]:区别DROP TABLE语句。
35) (条件删除) 将emp表无佣金及佣金低于500的salesman数据。
DELETE FROM emp
WHERE job=’salesman’ AND (comm IS NULL OR comm < 500.0) ;
- 视图的概念
由其他表(基表/视图)导出的虚表,可用于定义外模式。又称为:导出表(derived table)
1.但视图中不直接包含数据(即不对应物理数据文件),其数据包含在导出它的基表中。视图仅仅保留了其构造信息(有关视图的定义信息,即逻辑定义)。因此,视图又被称为’虚表’(virtual table)
2.由于数据库中只存放视图的定义,不会出现数据冗余。
3.当用户执行视图上的访问操作时,DBMS将根据视图的定义命令将用户对于视图的访问操作转换称相应基表上的访问操作。
4.基表中的数据发生变化,从视图中查询出的数据也随之改变。
视图的作用
1.视图能够简化用户的操作
2.视图使用户能以多种角度看待同一数据
视图机制能使不同用户以不同方式看待同一数据,适应数据库共享的需要
3.视图对重构数据库提供了一定程度的逻辑独立性
4.视图能够对机密数据提供安全保护
对不同用户定义不同视图,使每个用户只能看到他有权看到的数据
36)创建全体员工工作所在地的视图。
CREATE VIEW emp-loc
AS SELECT empno, ename, loc
FROM emp, dept
WHERE emp.deptno = dept.deptno
37)创建12号部门全体员工年薪视图。
CREATE VIEW emp-ann-sal (eno, ename, ann-sal)
AS SELECT empno, ename, 12*sal
FROM emp
WHERE deptno = 12 ;
撤销视图的语句格式
DROP VIEW <视图名>
例:DROP VIEW emp-loc;
- 视图上的查询
对用户而言
如同在基表中查询数据一样,使用SELECT语句。
对系统而言
需进行视图消解(resolution):
38)查询在南京工作的全体员工名单。
a.
SELECT ename
FROM emp-loc
WHERE loc=’Nanjing’;
b.
SELECT ename
FROM emp, dept
WHERE loc=’Nanjing’ AND emp.deptno =dept.deptno ;
39)假如创建部门平均薪水的视图。
CREATE VIEW emp-avg-sal (deptno, avg-sal)
AS SELECT deptno, AVG(sal)
FROM emp
GROUP BY deptno ;
3 CH04 数据库管理系统引论
- 事务
事务(Transaction):是DBMS的(最小、完整的)执行单位,它由某个用户所执行的一个不能被打断的对数据库的操作序列(SQL语句)组成,且必须满足ACID性质 。
A.原子性(Atomicity): 在一个事务中,所有的数据库访问操作是一个不可分割的操作序列,事务中的操作要么全做要么全不做(nothing or all)
e.g. 从ATM机取款时,“发钱登记”与“扣款”操作必须组成原子的事务。
C.一致性(Consistency): 事务在功能上必须使DB从一致状态(consistent state)变成另一个一致状态。即DB中的数据必须满足已定义的完整性约束和业务规则。
e.g. 银行DB:某帐号上的收支之差应始终等于余额。
I.隔离性(Isolation): 多个事务并发执行时彼此不受影响,就好象各个事务独立执行一样。
e.g. 民航DB:某航班就剩一张机票,有两个客户同时提出购买请求,结果应是一个买到,一个买不到。
D.持久性(Durability): 事务一旦成功执行,其对DB的影响应是持久的,即使DB发生故障也应保留这个事务的执行结果。
e.g. 银行的存款数据应是持久的。 - 提交和回滚
事务的两种结束方式
1.提交(Commit):全做事务中的操作。
2.回滚(Rollback):全不做事务中的操作(部分已执行的操作要撤消)。
提交和回滚可以是显式的、也可以是隐式的:
当发出COMMIT语句/ROLLBACK语句时显式提交/回滚当前事务;
当发出一个DDL语句时,前后均隐式提交一个事务;
当用户撤消对DBMS的连接时,当前事务隐式提交;
当用户进程异常中止时,当前事务隐式回滚。 - DBMS系统结构
单进程结构 / 单用户结构 / 单用户Oracle
应用代码和DBMS代码结合成单个进程而执行。e.g. MS-DOS上的单用户Oracle。
多进程结构 / 多用户结构 / 多用户Oracle
1.应用代码与DBMS代码组成同一个进程 / User/Server相结合的进程结构 / 单任务:。
2.一个应用代码对应一个DBMS核心进程 / 使用专用服务器进程的结构 / 两任务Oracle
单核心进程、多线程的DBMS进程结构 / 使用共享服务器进程的结构
多线程DBMS (Multithreading DBMS):不使用OS提供的多线程机制,而由DBMS自己实现多线程机制。
DBMS系统结构
1.集中式数据库
数据集中存储;由DBMS集中管理
2.分布式数据库系统
物理上分布、逻辑上集中的分布式数据库系统
物理上分布、逻辑上分布的分布式数据库系统 - 数据目录(字典)
是一组关于数据的数据(即元数据metadata),其中包含了数据库的各种定义信息、描述信息和统计信息。
4 CH05 关系数据库中表的典型存储机制
- 索引
通过一棵有序树(如B树)将索引键(Index Key, IK)值与数据块(的地址)建立联系,以提高数据检索性能。按照某个属性(项)的取值进行排序而构成的数据文件被称为顺序文件。(索引键值)
索引键如是PK或UNIQUE列,称主索引(Primary Index),否则称次索引(Secondary Index)。
主索引由于没有两行在索引键上具有重复值,故也称唯一索引(Unique Index)。
一般地,唯一索引由DBMS自动建立,而非唯一索引则需由DBA/用户自己显式地建立。
索引键可以是列组,此时称组合索引(Composite Index)。
稠密索引
索引文件
存放记录的索引键值以及指向记录本身的指针(记录的存储地址),并且按照索引键值的顺序进行排序。
一个索引键值和一个记录指针构成的键-指针对,称为一个索引项:
若每个索引键值均有对应的索引项(Index Entry),称这样的索引结构为稠密索引。
利用稠密索引进行数据查找要比直接在数据文件上进行数据查找的速度快。
非稠密索引
如果数据文件是顺序文件,我们可以在索引文件中只为数据文件的每个物理块设一个索引项,记录该物理块中第一条数据记录的索引键值及该物理块的首地址。这样建立起来的索引文件被称为非稠密索引。
区别
稠密索引与稀疏索引的区别
索引文件的定义不同
非稠密索引只能用于顺序文件上的索引组织。
稠密索引中的每个索引项对应数据文件中的一条记录,而非稠密索引中的每个索引项则对应数据文件中的一个物理块。
需要的磁盘空间大小不同
在记录的查找定位功能上存在差别:
稠密索引:可以直接回答是否存在键值为K的记录。
非稠密索引:需要额外的磁盘I/O操作,即需要将相应的数据文件中的磁盘块读入内存后才能判别该记录是否存在。
设一个关系有106个元组,在每个物理块(大小为4KB)中可存放10个这样的元组,则该关系大约占用:
105个磁盘块(约400MB)
设该关系中的元组已经按照主键值从小到大的顺序构成了一个顺序文件,因此可以采用二分查找法来根据主键值进行记录定位。
按照一个主键的值进行记录定位所需要的磁盘I/O次数为:
log2105 ≈ 16.6 ≈ 17
为例1中的顺序数据文件建立一个稠密索引。假设每个磁盘块可以存放100个索引项,则该稠密索引共有106个索引项,需要占用:
104个磁盘块(约40MB)
利用该稠密索引进行记录定位需要的磁盘I/O次数为:
log2104 + 1 ≈ 13.3 + 1 ≈ 15
其中的1是访问数据文件的磁盘I/O。
为例1中的顺序数据文件再建立一个非稠密索引。由于该数据文件共占用105个磁盘块,因此非稠密索引文件中有105个索引项,需要占用:
103个磁盘块(约4MB)
利用该非稠密索引进行记录定位需要的磁盘I/O次数为:
log2103 + 1 ≈ 9.97 + 1 ≈ 11
在例2中建立的稠密索引文件上再建立一个非稠密索引。由于例2中的稠密索引文件共占用104个磁盘块,因此新建立的非稠密索引文件中有104个索引项,需要占用100个物理块(约400KB)
在例3中建立的非稠密索引文件上也可以再建立一个非稠密索引。由于例3中的非稠密索引文件共占用103个磁盘块,因此新建立的非稠密索引文件中有103个索引项,只需要占用:10个物理块(约40KB)
非顺序文件中的索引结构
在数据库系统中所使用的数据文件通常都是无序的(堆文件组织),因此更加需要利用上述的索引结构来建立非顺序文件上的索引,以提高记录查找的速度。
如果索引键值在非顺序数据文件中具有唯一性,则可以按照下述步骤建立其上的索引文件:首先为非顺序数据文件建立第一级的稠密索引;然后再根据需要建立该稠密索引上的多级非稠密索引。
在次索引中,索引键值不唯一,则可以通过在第一级的稠密索引和数据文件之间加一个记录指针桶(bucket)。此时索引项(Ki,Pi)中的记录指针Pi不再是指向数据文件中的记录,而是指向一个记录指针桶,在桶中存放着索引键值为Ki的记录的记录指针。
- 散列
散列(Hash)是与表或簇集相关的一种可选存储机制,由于可通过一个Hash函数将散列键(Hash Key)的值映射成一个数据块的地址,给出散列键的值Ki立即可通过h (Ki)得到其对应的存储物理块地址,从而可明显改进数据检索的性能。 - 簇集
簇集(Cluster)是存储表数据的一种可选方法。
一个簇集是一个/组表,这个/组表中具有同一公共列(组)值的所有行均存储在一起(即物理上同一或相邻的数据块中)。这些公共列(组)称簇集键(Cluster Key, CK)。
5 CH06 查询处理和优化
- 代数优化
策略
尽可能缩减查询过程中的中间结果
1.先做选择、投影,后做连接、并;
2.先做小关系间的连接/笛卡尔积,后做大关系间的连接/笛卡尔积;
3.将“笛卡尔积+选择”合并为“连接”;
4.对原始关系加必要的投影,以消除对查询无用的属性。
常用等价变换规则
如果选择条件F所使用的属性全在属性集list中
如果F中所涉及的属性都是 R中的属性,即:
如果F1中所涉及的属性都是R中的属性,F2中所涉及的属性都是S中的属性,即:
例子:
SELECT ename, dname FROM emp, dept
WHERE emp.deptno=dept.deptno AND job=’clerk’ AND
loc=’Xian’ ;
- 依赖存取路径的规则优化
存取路径“用簇集连接存取单行”的选择条件是:
此路经适合于连接存储于同一簇集中的表,且如下两个条件为“真”:
WHERE子句中有条件:“一个表的簇集键列等于另一表的对应列”;
WHERE子句中有条件:“连接后只返回单行结果”。
若表emp与dept已在deptno列上建簇集,则下列查询可用以上存取路径:
SELECT empno, ename, dname, loc
FROM emp, dept
WHERE emp.deptno=dept.deptno AND empno=1001 ;
6 CH07事务处理
- 三类故障和三类恢复技术
事务失效(Transaction Failure):指事务因不可预知的原因而夭折,这些原因可能是:
1.事务因运行时出错(Run-time Error)而无法继续执行;
2.用户突然要求撤销事务;
3.系统调度时强行中止事务的运行,etc。
特证:发生在事务提交完成前。
系统失效(System Failure):指掉电或系统(OS或DBMS)发生故障而导致数据库系统无法继续正常运行下去,此时必须重新启动(Restart),从而导致一切事务无条件中止运行。
特征:内存数据全部丢失,但外存上的数据库未遭破坏。
介质失效(Media Failure): 指数据库存储介质(通常是磁盘)发生故障而导致不可读/写盘或盘中数据丢失。
特征:外存上的数据库已遭破坏,一切已提交的事务对数据库的影响全部丢失。
介质故障比前两类故障的可能性小得多,但破坏性大得多。
数据后备复本 (backup)
后备复本 (Backup):周期性地把(磁盘上的)数据库物理文件复制(称转储Dumping)到磁带上,建立副本。
方法:一旦发生故障,利用后备复本重装数据库,从而达到恢复目的。
运行记录/日志 (logging)
从数据库建立并开始运行起,记录全部提交事务对数据库的所有更新操作的文件,包括以下内容:
事务及其状态:
事务标识(TID)
提交了(commit) / 回滚了(rollback)?
前像 & 后像
前像(Before Image, BI):每次更新时,数据块的旧值。(插入时,BI为空)。
后像(After Image, AI):每次更新时,数据块的新值。(删除时,AI为空)。
方法:
有了BI,如果需要,可使DB恢复到更新前的状态(可撤销更新)—— 称撤销(Undo);
有了AI,如果需要,可使DB恢复到更新后的状态(可重做更新)—— 称重做(Redo)。
因此,有了日志,当发生故障时,可通过以下方法完全恢复DB:
若数据库未遭破坏,则从最近一致状态开始,对未提交事务进行Undo—向后恢复(Backward Recovery);对已提交事务进行Redo—向前恢复(forward Recovery)。
若数据库遭破坏,则先重装最近的Backup(后备副本),再对Backup以来的所有已提交事务进行Redo。
多复本
基于多复本的恢复技术
独立失效模式(Independent failure Mode):不致因同一故障而一起失效(因为支持环境是独立的)。
方法:系统中保持多个具有独立失效模式的数据库复本,互为备份、互为恢复的依据。
例如:镜像(Mirroring)技术,Mirrored Disks / Mirrored Files
“同时写,任选读”—对性能影响不大,有时可能反而提高性能。 - 更新事务的两条规则
为保证数据库是可恢复的,更新事务在系统具有日志机制后,其执行应遵守下列两条规则:
提交规则(Commit Rule)
后像AI必须在事务提交前写入非易失存储器(即数据库或日志文件)。
通常是立即写入DB Buffer Cache和Log文件,以便当发生故障时,能通过Redo而恢复。
先记后写规则(Log Ahead Rule)
如果AI在事务提交前写入数据库,则必须首先把BI记入日志。
写日志文件操作:把表示这个修改的日志记录写到日志文件
写数据库操作:把对数据的修改写到数据库中
以便一旦事务在提交前瞬间失败时,能通过Undo而恢复。
根据后像(AI)写入数据库的时间不同,有三种可选方案
1.后像在事务提交前完全写入数据库
2.后像在事务提交后才写入数据库
3.后像在事务提交前后写入数据库
恢复中最经常使用的技术:数据后备复本和日志
恢复的基本原理:利用存储在后备副本、日志文件和数据库镜像中的冗余数据来重建数据库
常用恢复措施
事务故障的恢复: UNDO
系统故障的恢复: UNDO + REDO
介质故障的恢复: 重装备份并恢复到一致性状态 + REDO
提高恢复效率的技术
检查点技术
可以提高系统故障的恢复效率; 在一定程度上提高利用动态转储备份进行介质故障恢复的效率。 - 并发访问与并发控制
多个事务的执行方式
1.串行访问(Serial Access):DBMS一次只可接纳一个事务,事务串行地被执行,即一个结束另一个才开始。
不能充分利用系统资源,发挥数据库共享资源的特点
2.并发访问(Concurrent Access):DBMS可以同时接纳多个事务,事务可以在时间上重叠地执行。
a.交叉并发方式(interleaved concurrency):并行事务的并行操作轮流交叉运行,是单处理机系统中的并发方式。能够减少处理机的空闲时间,提高系统的效率。
b.同时并发方式(simultaneous concurrency): 多处理机系统中,每个处理机可以运行一个事务,多个处理机可以同时运行多个事务,实现多个事务真正的并行运行。最理想的并发方式,但受制于硬件环境。更复杂的并发方式机制。
并发访问环境下,还能保证所有事务都满足ACID准则吗?—回答是:如果不加“控制”,那么就不能!
并发访问所引起的不一致问题
丢失更新(Lost Update)
源于:写—写冲突(Write—Write Conflict)
丢失更新是指事务1与事务2从数据库中读入同一数据并发地写入,事务2的提交结果破坏了事务1提交的结果,导致事务1写入的数据被丢失。
读脏数据(Dirty Read)
源于:读—写冲突(Read—Write Conflict)
事务1修改某一数据,并将其写回磁盘。事务2读取同一数据后,事务1由于某种原因被撤消,这时事务1已修改过的数据恢复原值。事务2读到的数据就与数据库中的数据不一致,是不正确的数据,又称为“脏”数据。
读值不可复现(Unrepeatable Read)
源于:读—写冲突
指事务1读取数据后,事务2执行更新操作,使事务1无法再现前一次读取结果。
三类读值不可复现
1.事务1读取某一数据后:事务2对其做了修改,当事务1再次读该数据时,得到与前一次不同的值。
2.事务2删除了其中部分记录,当事务1再次读取数据时,发现某些记录神密地消失了。
3.事务2插入了一些记录,当事务1再次按相同条件读取数据时,发现多了一些记录。
后两种不可重复读有时也称为幻影现象(phantom row)
并发控制
调度(Schedule):在某一时刻,DBMS对并发访问的一组事务 {T1,T2,…,Tn}的所有操作步骤的顺序的一个安排,可形式地表示成:
S = …Ri(x)…Wj(x)…Rk(y)… i、j、k∈{1,2,…,n},
Ri(x)表示事务Ti对数据x的一个读操作, Wj(x)表示事务Tj对数据x的一个写操作, Rk(y)表示事务Tk对数据y的一个读操作。
可见对同一个{T1,T2,…,Tn}有多种调度S。
串行调度(Serial Schedule)
导致事务串行访问的调度。
对于任何两个事务T和T’,如果T的某个action在T’之前,那么T的所有actions都在T’之前,这样的调度称为串行的。
只要一致性得到保证,最终的结果值并不是主要的。(在两个调度中,最终结果值可能会不一样)
并发控制的正确性准则
有两种操作对是冲突的,分别:
读—写冲突:表示为:Ri(x)和Wj(x)
写—写冲突:表示为:Wi(x)和Wj(x)
另三种操作对是不冲突的,分别是:
Ri(x)和Rj(x),Ri(x)和Rj(y),Wi(x)和Wj(y)
不冲突的操作之间可以相互调换次序,不会影响执行结果。
冲突等价(Conflict Equivalence):通过调换(不同事务间的)不冲突操作次序而得到的新调度。
可见,目标等价更普遍,冲突等价的调度→目标等价的调度。
等价的调度:给定对同一组事务的两个调度S1和S2,如果在DB的任何初始状态下,所有从DB中读出的数据都是一样的,留给DB的最终状态也是一样的,则称S1和S2是等价的调度。这种等价也称目标等价(View Equivalence)。
串行调度(Serial Schedule):导致事务串行访问的调度。
并行调度(Concurrent Schedule):导致事务并行访问的调度。
可串行化调度(Serializable Schedule):如果一个调度与某个串行调度是等价的,则称它为可串行化调度。
同样有:冲突可串行化、目标可串行化
冲突可串行化→目标可串行化
由于串行调度导致事务的串行访问(事务间不会有相互影响),总能保持数据库的一致性。可串行化调度与串行调度等价,因此,可串行化调度也总能保持数据库的一致性。
可串行化是并行事务正确性的唯一准则
结论
由于“可串行化调度”能保持DB的一致状态,因此,一般DBMS都以可串行化作为并发控制的正确性准则
“目标可串行化”比“冲突可串行化”更普遍,但由于其测试算法是NP完全问题,而后者可通过简单算法(如前超图(Precedence Graph)拓扑排序法)来判断,故总是以“冲突可串行化”作为具体的正确性准则。(即使明知会漏掉一些可串行化调度)
可串行化是并行事务正确性的唯一准则
结论:
1.由于“可串行化调度”能保持DB的一致状态,因此,一般DBMS都以可串行化作为并发控制的正确性准则。
2.“目标可串行化”比“冲突可串行化”更普遍,但由于其测试算法是NP完全问题,而后者可通过简单算法(如前超图(Precedence Graph)拓扑排序法)来判断,故总是以“冲突可串行化”作为具体的正确性准则。(即使明知会漏掉一些可串行化调度)
加锁协议
然而在实际系统中,不可能“通过检测是否可串行化”来控制并发访问、保证正确性准则。而是通过遵守“加锁协议”(Locking Protocol)“的办法来保证以上正确性准则的。(因为:事务是随机到达和退出的,没有一个固定的事务集等待DBMS调度/或者事务集一直在动态变化,难道频繁地“检测”吗?)
一用“加锁”,即可能产生活锁(Live Lock)和死锁(Dead Lock)之问题,由此即产生了如何检测和如何预防的问题。
在事务并发调度时,遵守“加锁协议”,即在执行任何事务的任一操作(R/W)之前对操作对象(数据)进行加锁,并遵循一定的协议,就可保证并发调度是(冲突)可串行化的,从而达到并发控制的目标。
合式事务
一个事务如果遵守“先加锁,后操作”的原则,则称此事务为合式事务(Well-formed Transaction)。
合式事务是保证并发事务的正确执行的基本条件。
两段事务和两段封锁协议
保证合法冲突可串行性所需附件的条件是“两段封锁协议”
定义:两段事务和两段锁协议
在一个事务中,如果所有加锁动作都在所有释放锁动作之前,则称这样的事务是两段事务(Two-Phase Transaction) — 隐含了X锁的加锁协议①。
以上限制也称两段封锁协议(two-Phase Locking protocol, 2PL协议)
定理:如果所有事务都是合式、两段事务,则它们的任何调度都是可串行化的。(充分单不必要)
死锁的预防
OS中防止进程死锁的思路:
一次申请所有锁
规定一个封锁次序
但是这在DB中不太实际。
DB中较实际的方法
选择性地“卷回重执” (Rollback and Retry)事务。
每个事务被DBMS接纳时被赋一个“时间标记”(Time Stamp,TS)。
若ts(TA) < ts(TB),则TA是“年老”者,TB是“年轻”者。
设TB已持有某对象的锁,当TA申请这一对象的锁而发生冲突时,有如下策略:
等待一死亡(Wait-Die)策略(若老则等,若幼则死)
if ts(TA) < ts(TB) then TA waits; / 老者等待 /
else { Rollback TA; / 幼者死亡 /
Restart TA with the same ts(TA); / 重执
/ };
年老者等待下去;年轻者死亡,稍后重执(其总会变得年老,而不会总死亡)
击伤一等待(Wound-Wait)策略 (若幼则等,若老则抢)
if ts(TA) > ts(TB) then TA waits; /* 幼者等待 /
else { Rollback TB; / 幼者击伤 /
Restart TB with the same ts (TB); / 重执
*/ };
年轻者被年老者击伤后重执而等待 (总会变得年老,而不会总被击伤)
以上策略的共性是:年轻事务作为牺牲品,卷回而重执。从而避免了循环等待!
7 CH08 数据库的安全与完整性描述
- 完整性约束及其类型
语义施加在数据上的限制。
利用完整性约束机制,可防止无效或错误数据进入DB,从而保证DB始终处于正确、一致的状态。
正确性:数据的有效性、有意义
一致性:在多用户(多程序)并发访问数据库的情况下,保证对数据的更新不会出现与实际不一致的情况。
完整性约束措施
1.完整性约束条件的定义及检查
2.触发器
3.并发控制技术
一条完整性约束规则一般有三个组成部分
完整性约束条件的设置
完整性约束条件的检查
在 DBMS 内部设置专门的软件检查模块。
完整性约束条件的处理
在用户的操作会破坏数据的完整性(即违反完整性约束条件的要求)时,系统将:
1.拒绝执行,并报警或报错;
2.调用相应的函数(例程)进行处理 ,如:在外键定义子句中给出的处理方法在触发器中给出的处理过程
完整性约束类型
1.静态约束(Static Constraints):对DB状态的约束。
a.固有约束(Inherent Constraints):指数据模型固有的约束。e.g. 关系数据模型中的1NF条件,etc.
b.隐含约束(Implicit Constraints):指隐含在数据模式中的约束,通常需用DDL来申明,约束的定义存于DD中。对关系模型来说,包括:
域完整性约束(Domain Integrity Constraints):
属性值应在域中取值、属性值是否可为NULL
实体完整性约束(Entity Integrity Constraints):
每个关系必须有一个键,每个元组的键值应唯一,且不能为NULL。
在SQL实现时,可为每个关系选定一个主键(PK)。
引用完整性约束(Referential Integrity Constraints):
一个关系中的FK值必须引用(另一个关系或本关系中)实际存在的PK值,否则只能取NULL。
c.显式约束
指更为广泛的语义约束,通常与特定的应用领域有关,其需用特定的DDL语句来申明,约束的定义存于DD中。
2.动态约束:指更为广泛的语义约束,通常与特定的应用领域有关,其需用特定的DDL语句来申明,约束的定义存于DD中。
显式约束与动态约束源于特定应用领域的业务规则,在关系数据库中称一般完整性约束(General Constraints)
- 用过程说明约束
当DBMS没有提供足够的支持完整性约束的机制时,完整性约束的说明与检查的任务就落在应用程序的身上,此时,称用过程说明约束。但其缺点是显然的:①加重了程序(员)的负担;②约束分散,难于统一管理与维护。 - 在基表中定义的约束
CREATE TABLE dept
(deptno INT PRIMARY KEY CONSTRAINT pk-dept,
dname VARCHAR(10) UNIQUE CONSTRAINT unq-dname,
loc VARCHAR(10) CHECK (loc IN (‘Shanghai’,’Nanjing’,
‘Wuhan’, ‘Xian’, ‘Beijing’)) CONSTRAINT ck-loc);
[例子]
- 断言说明的约束
在基表的定义命令中,可以定义很复杂的、基于属性或元组的完整性约束条件,并且可以在约束条件中使用到其它的关系。
[例]不允许‘英语系’(English)的学生选修‘CET-4’ 课程。则在创建‘选课’关系时可以定义一个完整性约束:
CHECK ( NOT
((SNO IN (SELECT SNO FROM Student WHERE Sd=‘English’) )
AND (CNO IN (SELECT CNO FROM Course WHERE Cn=‘CET-4’))
) );
问题:该完整性约束只对定义它的‘SC’关系起作用,而对‘Student’关系则不起作用。如果一个正在选修CET-4课程的学生转到英语系(将‘系别’属性的值修改为‘English’),这无疑会破坏‘SC’关系的数据完整性。
CHECK约束仅对定义它的关系的相应属性/元组起作用。为了使约束对整个关系模式(中的所有相关关系)均起作用,SQL2 / SQL:1999引入了一种全局约束(Global Constraints)机制——断言(Assertion),用于声明数据库状态必须满足的条件。
当数据库更新事件发生时,DBMS检测这种“更新”是否会导致“条件”不满足,若是,则拒绝这种“更新”的执行。
定义断言
CREATE ASSERTION <name> CHECK( <condition> );
例: (对单个关系的整体)每门课程的选修人数不少于20人。
CREATE ASSERTION ass_1 CHECK (
20 >= ALL ( SELECT COUNT(*)
FROM SC
GROUP BY CNO ));
例: (对多个关系间的联系)学生在选修‘数据结构’(DS)课程之前必需先选修过‘C++程序设计’(CPP)课。
CREATE ASSERTION ass_2 CHECK (
NOT EXISTS (
SELECT * FROM SC
WHERE CNO IN ( SELECT CNO FROM Course
WHERE CNAME = ‘DS’ )
AND
SNO NOT IN ( SELECT SC1.SNO
FROM SC SC1, Course
WHERE SC1.CNO = Course.CNO
AND Course.CNAME=‘CPP’ )
) );
断言实际上定义了一种通用的约束(General Constraints),从这种意义上说,前述的域完整性约束、引用完整性约束和CHECK约束是特殊类型的断言。
断言机制方便了程序员声明约束,但会导致DBMS复杂的“检测”动作,因此,断言在DBMS产品中是难于实现的(大多没有实现)。
- 触发器
触发器(Trigger):在数据库系统中,一个事件的发生会导致另外一些事件的发生,这样的功能被称为触发器。
触发器也称ECA rules, 是DBMS中的主动机制。当“事件”发生时,DBMS检测“条件”是否满足,若满足,则执行“动作”。
触发器的功能:某个事件的发生会导致另外一些事件的执行,以消除前一个事件对数据完整性所起的影响。
触发器最初是用于数据的完整性约束,但现在已经远远超出了此范围,也被应用于其它的目的,如:
1.数据的安全性保护
2.用户的应用逻辑处理
3.数据库系统的主动功能
触发器的组成
触发事件 (由用户定义)
通常为某个完整性约束条件的否定或某种数据操纵事件
如:用户登录,数据的增、删、改等
结果事件 (由用户定义)
当触发事件发生时,用以消除触发事件所引起的负面影响的程序。
通常是一组由用户书写的SQL命令
触发过程
当 DBMS 检测到触发事件的发生时,自动调用并执行结果事件的过程。
8 CH09 触发器与主动数据库系统
- 主动数据库系统
被动数据库系统:传统数据库系统只能按用户或应用程序(用户事务)的要求对数据库进行操作,而不能根据发生的事件或数据库的状态主动进行某些操作,这样的系统称为被动数据库系统(Passive Database System)。
主动数据库系统:理想的数据库系统应能根据发生的事件(如:用户事务对数据库进行某种操作、时间事件、外来事件等)或数据库的状态,主动地进行某些操作(称具有主动数据库功能),而且,这种主动数据库功能是用户/DBA事先可定义的,这样的系统称为主动数据库系统(Active Database System)。
实现方法:在数据库系统中引入规则(Rule)机制。因此,主动数据库系统有时也称规则系统(Rules System)。
主要规则
条件-动作规则 (Condition-Action rule, CA rule)
当数据库达到某种状态时(即“条件”满足时),触发DBMS执行“动作”。
注: CA规则作为主动数据库规则有缺陷,因此,当前大多数DBMS并不支持。
事件-条件-动作规则 (Event-Condition-Action rule, ECA rule)
当某个“事件”发生时,DBMS检测“条件”,若满足,则其执行“动作”。ECA规则也称触发器(Trigger)。
注: SQL标准从SQL:1999开始增设了触发器;当前,大多数DBMS已支持触发器,但实现功能和语法不尽相同,与SQL标准语法也不尽一致
ECA规则的种类
“事件”:SQL操纵语句(INSERT, DELETE, UPDATE)
“动作”执行频度
Each ROW:对“事件”导致的每个“行”操纵,“动作”执行一次。
Each STATEMENT:对整个“事件”,“动作”执行一次。
“动作”执行时刻/方式
BEFORE:“动作”在“事件”前执行。
AFTER:“动作”在“事件”后执行。
INSTEAD OF:“动作”替代“事件”而执行(“事件”语句不执行)。(SQL:1999中没有INSTEAD OF触发器,ORACLE系统中支持此种触发器)
触发器定义
<触发器定义> ::= CREATE TRIGGER <触发器名>
{BEFORE∣AFTER} <事件> ON <表名>
[REFERENCING
OLD {ROW∣TABLE} AS <过渡行/表标识符>,
NEW {ROW∣TABLE} AS <过渡行/表标识符>]
FOR EACH {ROW∣STATEMENT}
[WHEN <条件>] <动作>;
<事件>::= INSERT∣DELETE∣UPDATE [OF <属性表>]
<条件>::= <SQL谓词>
<动作>::= <SQL DML语句>∣
BEGIN <SQL DML语句>[; <SQL DML语句>]… END
[例]
CREATE TRIGGER sal_never_lower
AFTER UPDATE OF sal ON emp /* 事件:更新emp表上sal列 */
REFERENCING
OLD ROW AS oldtuple, /*建立过渡变量(transition variable),
表示旧元组*/
NEW ROW AS newtuple /* 建立过渡变量,表示新元组*/
FOR EACH ROW
WHEN oldtuple.sal > newtuple.sal /* 条件:当薪水值变低时 */
UPDATE emp
SET sal = oldtuple.sal /* 动作:薪水值恢复 */
WHERE empno = newtuple.empno;
9 CH10数据依赖与关系模式规范化
- 关系模式的比较
一个学生数据库中有以下属性:学号(SNO), 课程号(CNO), 成绩(G), 任课教师姓名(T), 教师所在系名(DEPT)。这些数据具有下列语义:
学号是一个学生的标识,课程号是一门课程的标识,这些标识与其表的学生和课程分别一一对应;
一位学生所修的每门课程都有一个成绩;
每门课程只有一位任课教师,但一位教师可以教多门课程;
教师中没有重名,每位教师只属于一个系。
方案一 方案二
一个关系 三个关系
R1 (SNO, CNO, G)
R (SNO, CNO, G, T, DEPT)
R2 (CNO, T)
R3 (T, DEPT)
比较方面:
1.数据冗余度
重复多次:“C01”课的教师是“张乐” ;“张乐”是“计算机”系的教师。
对于方案二,则不存在数据冗余
2.元组插入操作
如果需要新开设一门尚未有学生选修的课程(C05, 许卓明),则无法构造出一个由SNO, CNO, G, T, DEPT属性值所组成的新元组,在表1中就无法执行元组的插入操作。
对于方案二,我们可以直接将元组(C05,许卓明)插入到关系R2中。
3.元组删除操作
“C01”课不开了,需删除表1中的前三个元组,“张乐”是“计算机”系的教师的信息也随着被删除。
对于方案二,我们可以仅在关系R1和R2关系中分别删除课程为“C01”的元组信息,但不会误删除掉“张乐”是“计算机”系教师的信息,其所对应的元组仍然保留在关系R3中。
4.元组更新操作
“张乐”调到“土木”系,而只改了其中一个元组的值,出现数据不一致。
“M03”课的教师换成“杨萍”, 而只改了其中一个元组的值,出现数据不一致。
对于方案二,只需分别修改R2和R3关系中的元组的值即可,不会出现数据不一致。
好的设计方案应该是:既具有合理的数据冗余度,又没有插入和删除等异常现象的出现。 - 数据依赖
由于在关系模式R中存在某些数据依赖,引起数据冗余和数据更新异常。解决方法:通过分解关系模式来消除其中不合适的数据依赖,即关系规范化。 - 如何设计好的关系模式:规范化、模式分解、范式
规范化
将一个关系模式按“语义单纯化”的原则进行合理的分解----称模式分解(Decomposition),以最终达到“一事一地(One Fact in One Place)”。
在每个关系中,属性与属性之间一定要满足某种内在的语义联系,这被称为关系的规范化。
模式分解的条件准则
起码:分解是无损的(Lossless):分解前后要等价,即对任何相同的查询总是产生相同的结果。(可通过“连接”分解后的诸关系重构原关系)。
理想:分解是保持依赖的(Preserving Dependencies):这需进一步论述。
范式
规范化(即模式分解)程度的一种测度。根据对属性间所存在的内在语义联系要求的不同,又可以将关系的规范化分为若干个级别,这被称为范式。
规范化程度并非越高越好
程度一般到BCNF/3NF已足够
策略
1.对更新频繁/查询较少的表:规范化 ------减少“异常”
2.对查询频繁/更新较少的表:规范化 ------提高“性能” - 函数依赖与范式
9.4.1 函数依赖
函数依赖:在一个关系模式R(U)中,如果一部分属性Y的取值依赖于另一部分属性X的取值,则在属性集X和属性集Y之间存在着一种数据依赖关系,我们称之为函数依赖。
1.完全/部分FD,2.平凡/非平凡FD,3.直接/传递FD
Armstrong公理系统
键(key)
两个算法:
1.属性集的闭包计算
2.关键字的计算
[例]:在学生关系模式 Student( SNO, Sname, Sdept, Sage) 中就存在下面的几组依赖关系:
{ Sname } 的取值依赖于 { SNO } 的取值
{ Sdept } 的取值依赖于 {SNO} 的取值
{ Sage } 的取值依赖于 {SNO} 的取值
[例]:在选课关系模式SC(SNO, CNO, Grade)中:
{ Grade } 的取值依赖于 { SNO, CNO } 的取值
函数依赖是语义范畴上的概念,只有根据属性间固有的语义联系才能归纳出与客观事实相符合的函数依赖关系,而不是仅从现有的一个或若干个关系实例中得出的结论。
特定的关系实例虽然不能用于函数依赖的发现,但可以用于否定某些函数依赖。
函数依赖反映的是同一个关系中的两个属性子集之间在取值上的依存关系,这种依存关系实际上也是一种数据完整性约束。因此,我们也可以通过对数据完整性约束条件的分析来寻找属性之间的函数依赖关系。
一个学生数据库中有以下属性:学号(SNO), 课程号(CNO), 成绩(G), 任课教师姓名(T), 教师所在系名(DEPT)。这些数据具有下列语义:
学号是一个学生的标识,课程号是一门课程的标识,这些标识与其表的学生和课程分别一一对应;
一位学生所修的每门课程都有一个成绩;
每门课程只有一位任课教师,但一位教师可以教多门课程;
教师中没有重名,每位教师只属于一个系。
有以下三个函数依赖:
1. SNO,CNO→G 2. CNO→T 3. T→DEPT
决定子
平凡依赖/非平凡依赖/完全非平凡依赖
设A, B是某模式的两个属性集,对函数依赖AB,
若B A,则称此函数依赖为平凡依赖(Trivial Dependency);
若B–A≠Ф,则称此函数依赖为非平凡依赖(Nontrivial Dependency);
若B∩A = Ф,则称此函数依赖为完全非平凡依赖(Completely Nontrivial Dependency)。
对于任一关系模式,平凡函数依赖都是必然成立的,它不反映新的语义,因此若不特别声明, 我们总是讨论非平凡函数依赖。
平凡依赖规则
完全依赖\部分依赖
传递依赖
与函数依赖有关的范式
范式:1NF,2NF,3NF,BCNF
键是完全依赖。
范式是符合某一种级别的关系模式的集合。
关系数据库中的关系必须满足一定的要求。满足不同程度要求的为不同范式。
各种范式之间存在联系:
1NF
1NF的定义为:符合1NF的关系中的每个属性都不可再分。表1所示的情况,就不符合1NF的要求。范式一强调数据表的原子性。
2NF
3NF
设有一个关系模式R∈1NF,若R的任一非平凡函数依赖XA满足下列两个条件之一: (1) X是超键, (2)A是主属性,则称R属于3NF,记为R∈3NF。
一个学生数据库中有以下属性:学号(SNO), 课程号(CNO), 成绩(G), 任课教师姓名(T), 教师所在系名(DEPT)。这些数据具有下列语义:
学号是一个学生的标识,课程号是一门课程的标识,这些标识与其表的学生和课程分别一一对应;
一位学生所修的每门课程都有一个成绩;
每门课程只有一位任课教师,但一位教师可以教多门课程;
教师中没有重名,每位教师只属于一个系。
若R∈3NF,则R的每一个非主属性既不部分函数依赖于候选键(2NF)也不传递函数依赖于键。
采用投影分解法将一个2NF的关系分解为多个3NF的关系,可以在一定程度上解决原2NF关系中存在的插入异常、删除异常、数据冗余度大、修改复杂等问题。
将一个2NF关系分解为多个3NF的关系后,并不能完全消除关系模式中的各种异常情况和数据冗余。
BCNF
全键关系:关系模型的所有属性组是这个关系模式的候选键。
模式分解
逻辑蕴含