关系数据库设计
数据库设计规范化
- 现实世界的实体模型通过建模转为信息世界的概念模型(E-R图)
- 概念模型经过模型转换, 得到数据库世界的数据模型(关系模型)
- 数据模型进一步规范化, 得到数据库结构模型

函数依赖理论
数据依赖: 一个关系内部属性与属性之间的约束关系
数据依赖的类型:
- 函数依赖(FD)
- 多值依赖(MVD)
- 其他
函数依赖(FD)
设R(U)是一个属性集U上的关系模式, X和Y是U的子集.
若对于R(U)的任意一个可能的关系r, r中不可能存在两个元组在X上的属性值相等, 而在Y上的属性值不等, 记作
eg:
Student(ID, Name, Age)
ID → Name
ID → Age只要ID相同, Name和Age就必须相同. 即Name=f(ID), Age=f(ID)
也称Name和Age函数依赖于ID, 记作
平凡函数依赖
在Y函数依赖于在X函数的基础上, 即
如果有
eg:
Student(ID, Name, Age)
ID, Name → Name // 平凡函数依赖
ID, Age → ID // 平凡函数依赖非平凡函数依赖
eg:
Student(ID, Name, Age)
ID → Name // 非平凡函数依赖
ID → Age // 非平凡函数依赖完全函数依赖
设X, Y是关系R的两个属性集合,
若
记作
.
部分函数依赖
若
eg:
Student_Course(StudentID, CourseID, StudentName, CourseName, Grade)
{StudentID, CourseID} → Grade // 完全函数依赖
{StudentID, CourseID} → StudentName // 部分函数依赖, 因为StudentName只依赖于StudentID, 没有CourseID也能确定StudentName
{StudentID, CourseID} → CourseName // 部分函数依赖传递函数依赖
设X, Y, Z是关系R的三个属性集合, 且
则称Z传递函数依赖于X.
eg:
Student(ID, Name, Age, DeptID, DeptName)
ID → DeptID
DeptID → DeptName
ID → DeptName // DeptName传递函数依赖于ID这里, DeptName不直接依赖于ID, 而是通过DeptID间接依赖于ID. 两个属性可能不在同一张表里.
闭包
设F是关系模式R的一个函数依赖集, X和Y是R的属性子集, 如果F中的函数依赖能够推出
被F逻辑蕴涵的函数依赖的全体构成的集合, 称为F的闭包, 记作F+.
闭包: 由一个属性或者一个属性集直接或间接推导出的所有属性的集合.
eg1:
R(A, B, C, D, E, G)的函数依赖集
F = {AB -> C, BC -> AD, D -> E, CG -> B}
求AB的闭包AB+
0. AB -> AB, 初始时AB+ = {A, B}
1. AB -> C, 因为AB都在AB+中, 所以AB+ = {A, B, C}
2. BC -> AD, 因为BC都在AB+中, 所以AB+ = {A, B, C, D}
3. D -> E, 因为D在AB+中, 所以AB+ = {A, B, C, D, E}
4. CG -> B, 因为C在AB+中, 但G不在AB+中, 所以无法推出B
最终AB+ = {A, B, C, D, E}第一范式
范式(Normal Form, NF)是指规范化的关系模式.
关系规范化理论是将不十分合理的关系模型转化为最佳关系模型的理论.
范式之间的关系:
某一关系模式R为第n范式, 记作
一个低一级范式的关系模式, 通过模式分解可以转换为若干高一级范式的关系模式的集合, 这种过程叫规范化.
一般都数据库设计满足第三范式就可以了.
第一范式(1NF)
原子性
每个字段必须是原子的, 不可再分的.
eg:
Student(ID, Address)
=>
Student(ID, Street, City, State, Zip)第二范式
消除部分依赖
如果一个关系满足1NF, 并且除了主键的其他列, 都依赖该主键, 则满足第二范式(2NF).
第二范式要求每个表只描述一件事情.
不存在非主键对主键的部分函数依赖, 即不存在某个非主键属性只依赖于主键的一部分属性.
eg:
Student_Course(StudentID, CourseID, StudentName, CourseName, Grade)
主键: {StudentID, CourseID}
StudentName部分函数依赖于主键, 因为StudentName只依赖于StudentID
CourseName部分函数依赖于主键, 因为CourseName只依赖于CourseID
不满足2NF
=>
Student(StudentID, StudentName)
Course(CourseID, CourseName)
Student_Course(StudentID, CourseID, Grade)
满足2NF第三范式(3NF)
消除传递依赖
如果一个关系满足2NF, 并且除了主键的其他列都不传递依赖于主键列, 则满足第三范式(3NF).
第三范式要求每个表只描述一个主题.
不存在非主键对主键的传递函数依赖. eg:
Student(ID, Name, Age, DeptID, DeptName)
主键: ID
DeptName传递函数依赖于主键ID, 因为ID -> DeptID, DeptID -> DeptName
不满足3NF
=>
Student(ID, Name, Age, DeptID)
Department(DeptID, DeptName)
满足3NFBC范式(BCNF)
如果对F+中所有形如
- X是R的超码
是平凡函数依赖(即 )
则称关系模式R满足BC范式(BCNF).
条件:
- 满足第三范式
- 对于任何依赖关系
, X都是超码
eg:
R(学号, 课程, 教师)
主码: {学号, 课程}
函数依赖:
学号, 课程 -> 教师
教师 -> 课程
不满足BCNF, 因为教师不是超码
=>
教师(教师, 课程)
学生(学号, 教师)
满足BCNF第四范式(4NF)
消除多值依赖
一个关系, 至少存在三个属性(A, B, C)才能存在这种关系.
对于每一个A值, 有一组确定的B值和C值, 并且这组B的值独立于这组C的值.
eg:
Student(ID, Hobby, Telephone)
由于ID可能对应多个Hobby, 也可能对应多个Telephone, 并且Hobby和Telephone是独立的, 因此主键必须是{ID, Hobby, Telephone}
这就是多值依赖产生的问题, 因此需要拆分
=>
Student_Hobby(ID, Hobby)
Student_Telephone(ID, Telephone)
满足4NF