1、理论概念
- 实体:现实世界中可区别于其他对象的“事物”或“对象”;
- 实体集:具有相同性质的实体集合,例如某个银行的所有客户的集合可被定义为实体集customer。
- 属性:实体集中每个成员所拥有的描述性性质,实体通过一组属性来表示,。
- 联系:多个实体间的相互关联;
- 联系集:同类联系的集合,例如borrower来表示客户及其银行贷款之间的关联。
- 元组:表中的一行就是一个元组。
- 超码:一个或多个属性的集合,这些属性的组合可以在一个实体集中唯一地标识一个实体。如果K是一个超码,则K的任意超集也是超码。超码的任意子集都不能成为超码,这样的最小超码称为候选码,主码是在同一实体集中区分不同实体的候选码。
- 主属性:一个属性只要在任何一个候选码中出现过,这个属性就是主属性。
- 非主属性:没有在任何候选码中出现过,这个属性就是非主属性。
- 函数依赖
- 码是能够唯一标识整条元祖的属性集,函数依赖则表达了唯一标识某些属性的值的约束。
- 如果存在一个关系模式R,有两组属性集合a,b,模式R上a->b成立的条件是,任意两个元祖t1和t2,如果t1[a]=t2[a],则t1[b]=t2[b]。例:bor_loan=(customer_id, loan_num, amount)表示银行客户集合customer与贷款集合loan之间的联系,其中loan_num->amoun函数依赖成立,贷款号可以确定唯一的贷款金额amount。
- 在某一关系r上给定的函数依赖集F,也可能可以推导出其他的函数依赖也在该关系上成立。例如给定模式r=(A,B,C),如果函数依赖A->B和B->C在r上成立,也可以推导出A->C上成立。使用F+符号表示F集合的闭包,也就是从给定的F集合能够推导出的所有函数依赖的集合。
- 在所有关系中都满足的函数依赖成为平凡的函数依赖,一般若属性集合a包含b,则称a->b的函数依赖是平凡的。当关系中属性集合b是属性集合a的子集时(b⊆a),存在函数依赖a→b,即一组属性函数决定了它的所有子集。
2、第一范式:属性不可分
当关系模式R中某个域的元素被认为是不可分的单元,这个域就是原子的。如果一个关系模式R的所有属性域都是原子的,就称关系模式R属于第一范式。
以下面图片为例,客户电话这一属性就不是原子的,因为还可以分为座机和手机,所以可设计客户编号、客户座机和客户手机为一个关系模式的属性,则此关系模式可认为符合第一范式的要求。

3、第二范式:非主属性完全依赖于码
第二范式建立在第一范式的基础上,消除了部分函数依赖,非主属性完全依赖于码。 部分函数依赖:设X,Y是关系R的两个属性集合,存在X→Y,若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。 例:存在模式R=(学号,姓名,系名,系主任,课程,成绩),则码是(学号,课程)有函数依赖:(学号+课程)->(姓名,系名,系主任)中,存在 学号->(姓名,系名,系主任)
设关系模式R(U),主键是W,X⊂W,Z是非主属性,R上存在X->Z,此时,W->Z就是一个部分依赖,可以将R进行如下分解:1、将R分解为R1(XZ)(主键是X)和R2(U-Z)(主键是W,外键是X);2、如果R1和R2还不是2NF,则重复上述过程,直到所有关系都满足2NF。
所以,可以将上述模式R分解为两个,分别是 R1=(学号,姓名,系名,系主任) R2=(学号,课程,成绩)
4、BC范式
人们比较满意的范式之一是Boyce-Code范式(BCNF),它能够尽量消除基于函数依赖能够发现的冗余。 具有函数依赖集F的关系模式R属于BCNF的条件:对所有F+中形如a->b的函数依赖,下面至少有一个成立:
- a->b是平凡的函数依赖(即a包含b);
- a是模式R的一个超码。
以仓库管理关系表为例: 假设有仓库管理关系表 (仓库ID, 管理员ID,存储物品ID,数量),且一个管理员只在一个仓库工作,一个仓库可以存储多种物品。 这个数据库表中存在如下函数依赖关系: (仓库ID, 存储物品ID) →(管理员ID, 数量) (管理员ID, 存储物品ID) → (仓库ID, 数量) (仓库ID) → (管理员ID)和(管理员ID) → (仓库ID) 其中(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是表的候选码,都可唯一标识表中的数据,表中的唯一非关键字段为数量,由于存在如下决定关系:(仓库ID) → (管理员ID)和(管理员ID) → (仓库ID),不满足BCNF的任何一个条件,所以此设计不符合BCNF。
仓库管理表在以下情况会出现异常: (1) 删除异常: 当仓库被清空后,所有"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。 (2) 插入异常: 当仓库没有存储任何物品时,无法给仓库分配管理员。 (3) 更新异常: 如果仓库换了管理员,则表中所有行的管理员ID都要修改。
针对不属于BCNF的模式R有其一般的分解规则,对于一个非平凡的函数依赖a->b,且a不是R的超码,设计中会用以下两个模式取代R: (a∪b)和(R-(b-a))。 (仓库ID) → (管理员ID)和(管理员ID) → (仓库ID) 可分解为: (仓库ID,管理员ID) (仓库ID,存储物品ID,数量)
5、第三范式
BCNF要求所有非平凡函数依赖是a->b的形式,其中a为超码,第三范式放松了这个约束允许非平凡函数依赖 的左边不是超码。 具有函数依赖集第三范式F的关系模式R属于第三范式的条件是, 𝐹^+ 中所有形如a->b的函数依赖中至少有以下之一成立:
- a->b是一个平凡的函数依赖;
- a是R的一个超码;
- b-a中的每个属性A都包含在R的一个候选码中(每个属性A可包含在不同的候选码中)。
以仓库管理关系表为例: 假设有仓库管理关系表 (仓库ID, 管理员ID,存储物品ID,数量),且一个管理员只在一个仓库工作,一个仓库可以存储多种物品。 这个数据库表中存在如下决定关系: (仓库ID, 存储物品ID) →(管理员ID, 数量) (管理员ID, 存储物品ID) → (仓库ID, 数量) (仓库ID) → (管理员ID)和(管理员ID) → (仓库ID) 其中前两个条件符合上述三个条件,对(仓库ID) → (管理员ID)依赖来说,b-a=(仓库ID),包含在(仓库ID, 存储物品ID) 候选码中,管理员ID也包含在(管理员ID, 存储物品ID) 中,所以这个设计模式属于第三范式,不属于BCNF。
6、第四范式
多值依赖:令R为一关系模式,令a⊑R且b⊑R,在任意合法关系r(R)中,对于r中任一对满足t1[a] = t2[a]的元祖对t1和t2,r中存在的元祖t3和t4(可参考下图),使得 t1[a] = t2[a] = t3[a] = t4[a] t1[b] = t3[b] t2[R-b] = t3[R-b] t2[b] = t4[b] t1[R-b] = t4[R-b] 定义:函数依赖和多值依赖集为D的关系模式R属于第四范式的条件是对D+中所有形如a->->b的多值依赖,至少有以下之一成立: a->->b是一个平凡的多值依赖 a是模式R的超码 多值依赖a->->b,如果b⊑a或b⋃a=R,则a->->b是平凡的。

以职工表为例: 例如,职工表(职工编号,职工孩子姓名,职工选修课程),在这个表中,同一个职工可能会有多个孩子,同一个职工也可能会有多个选修课程。 职工编号->->职工孩子姓名 职工编号->->职工选修课程 但以上多值依赖不符合第四范式的两个条件,所以职工表模式不属于第四范式,只需要将上表分为两个表,使它们只有一个多值事实。例如职工表一(职工编号,职工孩子姓名),职工表二(职工编号,职工选修课程),两个表都只有一个多值依赖,所以符合第四范式。
7、综述
以上就是数据库设计中涉及到范式,但是真正开发中不仅需要了解理论,更需要符合各种真实情景,针对不同情况采用适合的设计。