问题的提出

数据依赖是一个关系内部属性与属性之间的一种约束关系。 这种约束关系是通过属性间值的相等与否体现出来的数据间相关联系。 它是现实世界属性间相互联系的抽象, 是数据内在的性质, 是语义的体现。

函数依赖(FunctionalDependency, FD) 和多值依赖( Multi-Valued Dependency, MVD)

函数依赖极为普遍地存在于现实生活中。 比如描述一个学生的关系, 可以有学号(Sno)、 姓名(Sname)、 系名(Sdept) 等几个属性。 由于一个学号只对应一个学生, 一个学生只在一个系学习。 因而当“ 学号” 值确定之后, 学生的姓名及所在系的值也就被唯一的函数值 地确定了。属性间的这种依赖关系类似于数学中的函数 y=f(X)。自变量x确定之后, 相应的函数值y也就唯一的确定了

[例6.1] 建立一个描述学校教务的数据库,该数据库涉及的对象包括学生的学号(Sno)、所在系(Sdept)、 系主任姓名(Mname)、 课程号(Cno)和成绩(Grade)。假设用一个单一的关系模式 Student 来表示, 则该关系模式的属性集合为
U ={Sno,Sdept,Mname,Cno,Grade}
现实世界的己知事实( 语义) 告诉我们:
① 一个系有若干学生, 但一个学生只属于一个系。
② 一个系只有一名(正职) 负责人。
③ 一个学生可以选修多门课程, 每门课程有若干学生选修。
④ 每个学生学习每一门课程有一个成绩。
于是得到属性组上的一组函数依赖 F (如图 6.1 所示)。 image-20211219193347568

如果只考虑函数依赖这一种 数据依赖,可以得到一个描述学生的关系模式Student <U,F>。表6.1 是某一时刻关系模式Student的一个实例,即数据表。

image-20211219193423912

但是, 这个关系模式存在以下问题:
(1) 数据冗余
比如, 每一个系的系主任姓名重复出现, 重复次数与该系所有学生的所有课程成绩出现次数相同, 如表 6.1 所示。 这将浪费大量的存储空间。
(2) 更新异常(update anomalies)
由于数据冗余, 当更新数据库中的数据时, 系统要付出很大的代价来维护数据库的完整性, 否则会面临数据不一致的危险。 比如, 某系更换系主任后, 必须修改与该系学生有
关的每一个元组。
(3) 插入异常(insertion anomalies)
如果一个系刚成立, 尚无学生, 则无法把这个系及其系主任的信息存入数据库。
(4) 删除异常(deletionanomalies)
如果某个系的学生全部毕业了, 则在删除该系学生信息的同时, 这个系及其系主任的信息也丢掉了。

假如把这个单一的模式改造一下, 分成三个关系模式:
S(Sno, Sdept, Sno–>Sdept);
SC(Sno, Cno, Grade, (Sno, Cno)–>Grade);
DEPT(Sdept, Mname, Sdept–> Mname);
这三个模式都不会发生插入异常、 删除异常的问题, 数据的冗余也得到了控制。

规 范 化

函数依赖

image-20211220115449457

image-20211219194433632

比如(Sno,Sdept)–>Mname,Mname不是(Sno,Sdept)子集,非平凡函数依赖

而(Sno,Sdept)–>Sdept,平凡函数依赖

image-20211219194426355

码是关系模式中的一个重要概念。 在第 2 章中已给出了有关码的若干定义, 这里用函数依赖的概念来定义码。
image-20211219194805402
image-20211219194924916
若候选码多于一个, 则选定其中的一个为主码( primary key)。
包含在任何一个候选码中的属性称为主属性 ( prime attribute); 不包含在任何候选码中的属性称为非主属性(nonprime attribute) 或非码属性 (non-key attribute)<, 最简单的情况,单个属性是码; 最极端的情况, 整个属性组是码, 称为全码( all-key)

求取候选码

  1. 只出现在左边或左右均不出现一定是候选码
  2. 只出现在右边一定不是候选码
  3. 左右都出现,带入进行推导才知道

例1:R<U,F>,U=(A,B,C,D,E,G),F={AB–>C,CD–>E,E–>A.A–>G},求候选码。

因G只在右边出现,所以G一定不属于候选码;而B,D只在左边出现,所以B,D一定属于候选码;BD的闭包还是BD,

则对BD进行组合,除了G以外,BD可以跟A,C,E进行组合
先看ABD
ABD本身自包ABD,而AB–>C,CD–>E,A–>G,所以ABD的闭包为ABDCEG=U
再看BDC
CD–>E,E–>A,A–>G,BDC本身自包,所以BDC的闭包为BDCEAG=U
最后看BDE
E–>A,A–>G,AB–>C,BDE本身自包,所以BDE的闭包为BDEAGC=U

因为(ABD)、(BCD)、(BDE)的闭包都是ABCDEG所以本问题的候选码有3个分别是ABC、BCD和BDE

范式

一个低一级范式的关系模式通过模式分解( schemadecomposition)可以转换为若干个高一级范式的关系模式的集合, 这种过程就叫规范化( normalization)。

如何理解关系型数据库的常见设计范式? - 刘慰的回答 - 知乎 https://www.zhihu.com/question/24696366/answer/29189700

第一范式

第一范式列不能再分。

下面情况不符合1NF的要求

img

第二范式

第二范式建立在第一范式的基础上,非主属性完全依赖于码。
简单说:消除部分依赖。

image-20211219195853365

(学号+课程)->姓名,但是学号->姓名

(学号+课程)->系名,但是学号->系名

(学号+课程)->系主任,但是学号->系主任

这个是部分依赖,因为课程起不到什么作用,因此把课程给拆开即可。一张是 学号、课程、分数表,另外一张是 学号、姓名、系名、系主任表

image-20211219200016225

第三范式

满足第二范式的条件下不存在传递函数依赖。

学号->系名,系名->系主任 传递依赖。需要将系名和系主任另外新建一张表。

image-20211219200302439

BCNF范式

BCNF范式

要了解 BCNF 范式,那么先看这样一个问题:

若:

  1. 某公司有若干个仓库;
  2. 每个仓库只能有一名管理员,一名管理员只能在一个仓库中工作;
  3. 一个仓库中可以存放多种物品,一种物品也可以存放在不同的仓库中。每种物品在每个仓库中都有对应的数量。

那么关系模式 仓库(仓库名,管理员,物品名,数量) 属于哪一级范式?

答:已知函数依赖集:仓库名 → 管理员,管理员 → 仓库名,(仓库名,物品名)→ 数量
码:(管理员,物品名),(仓库名,物品名)
主属性:仓库名、管理员、物品名
非主属性:数量
∵ 不存在非主属性对码的部分函数依赖和传递函数依赖。∴ 此关系模式属于3NF。

基于此关系模式的关系(具体的数据)可能如图所示:

img

好,既然此关系模式已经属于了 3NF,那么这个关系模式是否存在问题呢?我们来看以下几种操作:

  1. 先新增加一个仓库,但尚未存放任何物品,是否可以为该仓库指派管理员?——不可以,因为物品名也是主属性,根据实体完整性的要求,主属性不能为空。
  2. 某仓库被清空后,需要删除所有与这个仓库相关的物品存放记录,会带来什么问题?——仓库本身与管理员的信息也被随之删除了。
  3. 如果某仓库更换了管理员,会带来什么问题?——这个仓库有几条物品存放记录,就要修改多少次管理员信息。

从这里我们可以得出结论,在某些特殊情况下,即使关系模式符合 3NF 的要求,仍然存在着插入异常,修改异常与删除异常的问题,仍然不是 ”好“ 的设计。

造成此问题的原因:存在着主属性对于码的部分函数依赖与传递函数依赖。(在此例中就是存在主属性【仓库名】对于码【(管理员,物品名)】的部分函数依赖。

解决办法就是要在 3NF 的基础上消除主属性对于码的部分与传递函数依赖。

仓库(仓库名,管理员)
库存(仓库名,物品名,数量)

这样,之前的插入异常,修改异常与删除异常的问题就被解决了。

简而言之,BCNF不可以出现非候选码能够决定非候选码的情况

以上就是关于 BCNF 的解释。

多值依赖

image-20211219204433345

注意这里一组Y若改为一个Y就是函数依赖的定义了。

image-20211219204513146

性质:

  1. 多值依赖具有对称性。
  2. 多值依赖具有传递性 。
  3. 函数依赖可以看作是多值依赖的特殊情况

第四范式

image-20211219204629594

总结

image-20211219204712176

关系模式的规范化过程是通过对关系模式的分解来实现的, 即把低一级的关系模式分解为若干个高一级的关系模式。 这种分解不是唯一的。 下面将进一步讨论分解后的关系模式与原关系模式“ 等价” 的问题以及分解的算法。