关系数据库理论
相关概念
关系:描述实体、属性、实体间的联系。从形式上看,它是一张二维表,是所涉及属性的笛卡尔积的一个子集。
关系模式:用来定义关系,是对关系的描述
关系数据库:基于关系模式的数据库。利用关系来描述现实世界从形式上看,它由一组关系组成。
关系模式有五部分组成,可以定义为
R(U,D,DOM,F)
- R:关系名
- U:组成该关系的属性名集合
- D:属性组 U 中属性所来自的域
- DOM:属性向域的映像集合
- F:属性间数据的依赖集合
数据依赖:是通过一个关系中属性间值的相等与否体现出来的数据间的相互关系,它是现实世界属性间相互关联的抽象。是数据内在的性质,是语义的体现。
数据依赖的类型分为函数依赖和多值依赖
由于 D 和 DOM 对模式涉及关系不大,在本节中把关系模式简化为一个三元组:R(U,F),研究重点为:
- 一个关系模式应该有哪些属性;
- 这些属性间存在什么样的联系
数据依赖的影响
- 冗余数据太大,浪费大量的存储空间。比如每个分组及组长重复出现
- 更新异常:数据冗余,在更新数据时,维护数据完整性代价大。比如如果要更改一名员工到另外一个组,则需要将这个员工的所有销售对应的分组和组长进行更新。
- 插入异常:该插的数据插不进去。比如由于主码中所包含的属性值不能取空值,如果新成立一个组,由于这个组还没分配员工,就无法将这个分组插入关系中
- 删除异常:不该删除的数据不得不删除比如如果某个分组的所有员工被调到其他分组,则这个组的信息会随所有组员的调动而全部丢失
“好”的关系模式不会发生插入异常、删除异常、更新异常,数据冗余应尽可能少。
原因:由存在于模式中的某些数据依赖引起的。解决方法:通过分解关系模式来消除其中不合适的数据依赖。
我们就可以把 SALE 关系分解为三个关系模式:
S1(ENO, SaleDate, SaleAmount)
S21(ENO, Group)
S22(Group, GName)
函数依赖
对于 R(U)上的任一一个可能的关系 r,如果 r 中不存在两个元组,它们在 X 上的属性值相同,而在 Y 上的属性值不同,则称X 函数决定 Y或Y 函数依赖于 X,记作X->Y
X 称为决定因素或决定属性集
说明:
- 函数依赖不是指关系模式 R 的某个或某些关系实例满足的约束条件,而是指 R 的所有关系实例均要满足的约束条件
- 函数依赖时语义范畴的概念
- 数据库设计着可以对现实世界作强制的规定
- 若
X->Y
,且Y->X
,则记X<-->Y
- 若 Y 不函数依赖于 X,则记作
X!=>Y
【例】关系模式学生(学号,姓名,出生年份,性别,学院,专业,微信号),假设不允许重名,则有:
- 学号 →出生年份 , 学号 →性别,学号 → 学院,学号 → 专业, 学号 → 微信号;
- 学号 ←→ 姓名;
- 姓名 →出生年份 , 姓名 →性别,姓名 → 学院,姓名 → 专业,姓名 → 微信号;
- 但性别→专业。
非平凡函数依赖
在关系模式 R(U)中,对于 U 的子集 X 和 Y,如果 X→Y,但 Y ⊈ X,则称 X→Y 是非平凡函数依赖(后续主要讨论这个);若 X→Y,但 Y⊆ X,则称 X→Y 是平凡函数依赖。
【例】在关系 R1(ENO,SaleDate,SaleAmount)中,个属性分别为员工编号,日期,销售量,每个员工每天会有一个销售额,存在如下函数依赖: 非平凡函数依赖:(ENO,SaleDate) → SaleAmount; 平凡函数依赖: (ENO,SaleDate) → ENO, (ENO,SaleDate) → SaleDate。
对于任一关系模式,平凡函数依赖都是必然成立的,它不反映新的语义,因此若不特别声明, 我们总是讨论非平凡函数依赖。
完全函数依赖
- 在关系模式 R(U)中,如果 X→Y,并且对于 X 的任何一个真子集 X’,都有 X’→ Y,则称 Y 完全函数依赖于 X,记作
- 若 X→Y,但 Y 不完全函数依赖于 X,则称 Y 部分函数依赖于 X,记作
【例】如在关系 R1(ENO,SaleDate,SaleAmount)中,由于ENO !=> SaleAmount, SaleDate !=> SaleAmount,
因此
传递函数依赖
• 在关系模式 R(U)中,如果 X→Y,Y→Z,且 Y ⊈ X,Y→X,递 则称 Z 传递函数依赖于 X,记作
【例】如在销售关系 R(ENO,SaleDate,SaleAmount,Group, GName)中,各属性分别为员工编号,日期,销售量,分组,组长,存在语义每个员工只能属于一个分组,每个分组只有一个组长,由于 ENO→Group,Group→GName,则
码
设 K 为 R(U,F)中的属性或属性组合。若
说明:
- 候选码可以唯一地识别关系的元组
- 包含在任何一个候选码中的属性,叫做主属性。不包含在任何候选码中的属性称为非主属性或非码属性
- 最简单的情况下,候选码只包含一个属性
- 最复杂的情况下,候选码包含关系模式的所有属性,称为全码。
关系模式 R 中属性或属性组 X 并非 R 的码,但 X 是另一个关系模式的码,则称 X 是 R 的外部码,简称外码。
第一范式
定义
- 如果一个关系模式 R 的所有属性都是不可分的基本数据项(不能表中有表),则 R 是第一范式,简称 1NF,记作 R∈1NF
- 第一范式是对关系模式的最起码的要求。满足第一范式的关系称为规范化关系。不满足第一范式的数据库模式不能称为关系数据库。
非规范化关系
规范化关系
问题
【例】校园超市数据库中有一个记录超市员工每天销售量的关系模式 SALE(U,F),其中 SALE 的属性由员工编号,日期,销售量,分组,组长等属相组成,U 如下所示: U={ENO,SaleDate,SaleAmount,Group,GName};现有语义规定,每个员工每天会有一个销售额,每个员工只能属于一个分组,每个分组只有一个组长。
结合现实世界的已知事实,可以分析得到属性组 U 上有如下函数依赖:
关系模式 SALE 满足第一范式,候选码是(ENO,SaleDate),但 SALE 关系存在很多问题:
- 数据冗余太大
- 更新异常
- 插入异常
- 删除异常
原因:Group、GName 部分函数依赖于码,GName 传递函数于依赖于码。
第二范式
定义
- 若关系模式 R∈1NF,且每一个非主属性都完全函数依赖于码,则称 R 为第二范式,简称 2 NF,记作 R∈2NF。
- 第二范式也可以理解为:不允许关系模式中存在这样的依赖:如果 X’是码 X 的真子集,有 X’→Y,其中 Y 是该关系模式的非主属性。
1NF 向 2NF 的转换
- 由第一范式向第二范式转换的方法是:消除其中非主属性对码的部分函数依赖,一般是将一个关系模式分解成多个 2NF 的关系模式。
- 即将部分函数依赖于码的非主属性及其决定属性移除,另外形成一个关系,从而满足 2NF。
【例】关系 SALE(ENO,SaleDate,SaleAmount,Group,GName)是 1NF,但存在非主属性 Group,GName 对码的部分函数依赖,采用分解法,把 SALE 分解为两个关系模式:
S1(ENO,SaleDate,SaleAmount)
S2(ENO,Group,GName)
其中 S1 的码为(ENO,SaleDate),S2 的码为 ENO。
分解之后的关系模式 S1 和 S2 中,非主属性都完全函数依赖于码了。S1 和 S2 的函数依赖图如图所示。
问题
- SALE 关系分解之后得到的 S1 关系和 S2 关系都是第二范式,在一定程度上能够减轻原关系中存在的各种异常问题。
- 但是将一个 1NF 关系分解为多个 2NF 关系,并不能完全消除关系模式中的各种异常情况和数据冗余。
- 一个属于 2NF 的关系模式也不一定是一个好的关系模式
【例】SALE 分解后得到的关系模式 S2(ENO,Group,GName)
- 是一个 2NF 的关系模式
- 不存在非主属性对码的部分函数依赖
- 但 S2 仍然存在问题:
- 数据冗余度大
- 插入异常
- 删除异常
- 更新问题
- 原因:存在非主属性 GName 传递函数依赖于码(没有员工不能插入组)
第三范式
定义
如果关系 R 为 2NF,并且R 中每一个非主属性都不传递依赖于 R 的候选码,则称 R 为第三范式,简称 3NF,记作 R∈3NF。
2NF 向 3NF 的转换
第二范式向第三范式转换就是消除非主属性对码的传递函数依赖。即将传递函数依赖于码的非主属性及其决定属性移除,另外形成一个关系,从而满足 3NF。
【例】关系模式 S2(ENO,Group,GName)是 2NF,但存在非主属性 GName 传递依赖于码 ENO,采用分解法,把 S2 分解为两个关系模式:
- S21(ENO,Group)
- S22(Group,GName)
其中 S21 的码为 ENO,S22 的码为 Group。分解之后的关系模式 S21 和 S22 中,不存在非主属性对码的传递函数依赖。S21 和 S22 的函数依赖图如图所示。
问题
- 将一个 2NF 的关系分解为多个 3NF 的关系,可以在一定程度上解决原 2NF 关系中存在的插入异常、删除异常、数据冗余度大、修改复杂等问题。
- 但是将一个 2NF 关系分解为多个 3NF 的关系后,并不一定能完全消除关系模式中的各种异常情况和数据冗余。
【例】校园超市数据库中有一个记录仓库商品管理的关系模式 SM(GoodsNO,StorageNO,ManagerNO,SNUM),各属性分别是商品编码,仓库编码,仓库管理员编码,商品的存放数量;现有语义规定:一个管理员只在一个仓库工作;一个仓库只有一个管理员管理;一个仓库可以存储多种商品,一种商品可以存放在不同仓库;每种商品在一个仓库存放有一个存放数量。
结合现实世界的已知事实,可以分析得到 SM 的属性组 上有如下函数依赖:
- StorageNO→ManagerNO
- ManagerNO→StorageNO
- (GoodsNO,StorageNO)→SNUM
- (GoodsNO,StorageNO)→ManagerNO
- (GoodsNO,ManagerNO)→StorageNO
- (GoodsNO,ManagerNO)→SNUM
SM 的候选码有两个:(GoodsNO,StorageNO)和(GoodsNO,ManagerNO)
关系 SM 中的唯一非主属性是 SNUM,它是完全依赖于候选码的,且不传递依赖于候选码。因此 SM 是符合第三范式的。
但 SM 关系仍然存在很多问题:
- 数据冗余太大
- 更新异常
- 插入异常
- 删除异常
原因:3NF 没有限制主属性对码的依赖关系,因此在 3NF 中,可能存在主属性的部分函数依赖和传递函数依赖,从而导致操作异常。
BC 范式
定义
- 关系模式是 1NF,如果对于 R 的每个函数依赖 X→Y,若 Y 不属于 X 时 X 必含有候选码,则称 R 为 BC 范式,简称 BCNF,记作 R∈BCNF。
- BCNF 的定义可以这样理解:如果关系 R 为 1NF,并且 R 中不存在任何属性对码的部分依赖或传递依赖,那么称 R 为 BCNF。
BCNF 的关系模式具有以下特性:
- 所有的非主属性对每一个码都是完全函数依赖。
- 所有的主属性对每一个不包含它的码,也是完全函数依赖
- 没有任何属性完全函数依赖于非码的任何一组属性
3NF 向 BCNF 的转换
3NF 和 BCNF 之间的区别在于,对一个函数依赖 X→Y,3NF 允许 Y 是主属性,而 X 不为候选码。但 BCNF 要求 X 必为候选码。因此 BCNF 的限制比 3NF 更严格,3NF 不一定是 BCNF,而 BCNF 一定是 3NF。
要将 3NF 关系向 BCNF 关系转换就是要消除主属性对码的部分和传递函数依赖。
【例】校园超市数据库中有一个记录仓库商品管理的关系模式 SM(GoodsNO,StorageNO,ManagerNO,SNUM),各属性分别是商品编码,仓库编码,仓库管理员编码,商品的存放数量;现有语义规定:一个管理员只在一个仓库工作;一个仓库只有一个管理员管理;一个仓库可以存储多种商品,一种商品可以存放在不同仓库;每种商品在一个仓库存放有一个存放数量。
结合现实世界的已知事实,可以分析得到 SM 的属性组上有如下函数依赖:
- StorageNO→ManagerNO
- ManagerNO→StorageNO
- (GoodsNO,StorageNO)→SNUM
- (GoodsNO,StorageNO)→ManagerNO
- (GoodsNO,ManagerNO)→StorageNO
- (GoodsNO,ManagerNO)→SNUM
SM 的候选码有两个:(GoodsNO,StorageNO)和(GoodsNO,ManagerNO)
- 关系 SM 中的唯一非主属性是 SNUM,它是完全依赖于候选码的,且不传递依赖于候选码。因此 SM 是符合第三范式的。
- 但 SM 存在主属性 ManagerNO 和 StorageNO 对码的部分函数依赖。不符合 BC 范式的要求。
- 为了消除主属性对码的部分函数依赖,分解 SM 为两个关系模式:
- SM1(GoodsNO,StorageNO,SNUM)
- SM2(StorageNO,ManagerNO)
- SM1 的候选码是(GoodsNO,StorageNO),SM2 的候选码是 StorageNO 或者 ManagerNO。SM1 和 SM2 都满足 BC 范式要求。
问题
在函数依赖范畴,BCNF 的关系模式规范化程度已经是最高了。但如果考虑其他数据依赖,那么属于 BCNF 的关系模式仍然存在问题,不能算是一个完美的关系模式。
【例】校园超市有一仓库商品管理的关系模式 WMG(W,M,G),其中 W 表示仓库,M 表示仓库管理员,G 表示商品。假设每个仓库有若干个仓库管理员,有若干种商品。每个仓库管理员管理多个仓库的多种商品,每种商品可以存放在多个仓库。
- 关系模式 W M G 的码是( W , M , G ) , 即全码, 因而 WMG∈BCNF。
- 但 WMG 关系仍然存在很多问题:
- 数据冗余
- 更新异常
- 插入异常
- 删除异常
- 原因:在 WMG 的属性间存在一种有别于函数依赖的依赖关系,它具有如下特点:
- 对于一个 W 值,如 W1,会有一组 M 值与之对应,如:M1,M2 与之对应。
- 仓库与仓库管理员的对应关系,与商品的取值无关。
多值依赖
- 设 R(U)是一个属性集 U 上的一个关系模式, X、Y 和 Z 是 U 的子集,并且 Z=U-X-Y,多值依赖 X→→Y 成立当且仅当对 R 的任一关系 r,r 在(X,Z)上的每个值对应一组 Y 的值,这组值仅仅决定于 X 值而与 Z 值无关。
- 若 X→→Y,而 Z=φ,则称 X→→Y 为平凡的多值依赖,否则称 X→→Y 为非平凡的多值依赖。
- 在关系模式 WMG 中,很显然存在着非平凡的多值依赖,即 W→→M,W→→G。
多值依赖与函数依赖相比,具有下面两个基本的区别:
- 若函数依赖 X→Y 在 R(U)上成立,则对于任何 Y’⊂Y 均有 X→Y’成立;而多值依赖 X→→Y 若在 R(U)上成立,我们却不能断言对于任何 Y’⊂Y 有 X→→Y’成立。
- 在关系模式 R(U)中函数依赖 X→Y 的有效性仅决定于 X,Y 这两个属性集的值。但是多值依赖的有效性与属性集的范围有关。
第四范式
定义
- 关系模式 R<U,F>∈1NF,如果对于 R 的每个非平凡多值依赖 X→→Y(Y⊆X),X 都含有候选码,则称 R 为第四范式,简称 4NF,记作 R∈4NF。
- 4NF 限制了关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。一个关系模式若属于 4NF,则必然属于 BCNF。
BCNF 向 4NF 的转换
BCNF 向 4NF 转换就是要消除非平凡且非函数依赖的多值依赖,以减少数据冗余,即将 BCNF 关系分解成多个 4NF 关系模式。
在 WMG 中,W→→M,W→→G,它们都是非平凡的多值依赖。而关系模式 WMG 的码是全码,即码为(W,M,G)。W 不是码,对照 4NF 的定义 WMG∉ 4NF。
采用分解的方法消去非平凡且非函数依赖的多值依赖。把 WMG 分解两个关系模式:
- WM(W,M)
- WG(W,G)
在 WM 中虽然有 W→→M,但这是平凡的多值依赖,且都不是函数依赖。WM 中已不存在非平凡且非函数依赖的多值依赖。所以 WM∈4NF,同理 WG∈4NF。
规范化小结
规范化步骤
- 1NF 经消除非主属性对码的部分函数依赖后为 2NF。
- 2NF 经消除非主属性对码的传递函数依赖后为 3NF。
- 3NF 经消除主属性对码的部分和传递函数依赖后为 BCNF。
- BCNF 经消除非平凡且非函数依赖的多值依赖后为 4NF。
规范化思想
- 消除不合适的数据依赖,采用“一事一地”的模式设计原则;
- 各关系模式达到某种程度的“分离”,实现概念的单一化
- 关系模式的规范化结果并不是唯一的,在设计数据库模式结构时,必须对现实世界的实际情况和用户应用需求作进一步分析,确定一个合适的、能够反映现实世界的模式
- 不能说规范化程度越高的关系模式就越好,要根据实际情况确定;前面的规范化步骤可以在其中任何一步终止。