函数依赖
函数依赖是关系数据库设计中的一个重要概念,用于描述属性之间的依赖关系。它在规范化理论中起着关键作用,帮助我们设计出无冗余、高效率的数据库模式。
定义
- 函数依赖:在一个关系模式 R 中,如果对于 R 的每一个可能的关系实例 r,属性集 X 的值唯一确定了属性集 Y 的值,则称 Y 函数依赖于 X,记作 X→Y。
- 形式化定义:设 R(U) 是一个关系模式,U 是 R 的属性集,X 和 Y 是 U 的子集。如果对于 R 的任意两个元组 t1 和 t2,当 t1[X]=t2[X] 时,必有 t1[Y]=t2[Y],则称 Y 函数依赖于 X,记作 X→Y。
基本术语
- 完全函数依赖:如果 X→Y,且不存在 X 的真子集 Z 使得 Z→Y,则称 Y 完全函数依赖于 X。
- 部分函数依赖:如果 X→Y,且存在 X 的真子集 Z 使得 Z→Y,则称 Y 部分函数依赖于 X。
- 传递函数依赖:如果 X→Y 且 Y→Z,但 X 不包含 Y 且 X 不函数依赖于 Z,则称 Z 传递函数依赖于 X。
示例
假设有一个关系模式 Employee
,其属性包括 EmployeeID
、Name
、DepartmentID
、DepartmentName
和 Salary
。
-
完全函数依赖:
EmployeeID → Name
:员工编号唯一确定员工姓名。EmployeeID → Salary
:员工编号唯一确定员工薪水。DepartmentID → DepartmentName
:部门编号唯一确定部门名称。
-
部分函数依赖:
(EmployeeID, DepartmentID) → Name
:组合键部分函数依赖于Name
,因为EmployeeID
单独就能确定Name
。
-
传递函数依赖:
EmployeeID → DepartmentID
:员工编号唯一确定部门编号。DepartmentID → DepartmentName
:部门编号唯一确定部门名称。- 因此,
EmployeeID → DepartmentName
是传递函数依赖。
第一范式
第一范式(1NF):每个属性都是原子的,即不可再分。
-
示例:
违反1NF的表:OrderID Products 1001 手机, 耳机 1002 笔记本电脑 符合1NF的改进:
OrderID Product 1001 手机 1001 耳机 1002 笔记本电脑
第二范式
第二范式(2NF):满足 1NF,并且所有非主属性都完全函数依赖于候选键。
-
示例:
原始表(候选键:(OrderID, ProductID)
):OrderID ProductID ProductName Quantity 1001 P001 手机 2 1001 P002 耳机 1 问题:
ProductName
仅依赖ProductID
(部分依赖)。
分解后:- 订单明细表(候选键:
(OrderID, ProductID)
):OrderID ProductID Quantity 1001 P001 2 - 产品表(候选键:
ProductID
):ProductID ProductName P001 手机
- 订单明细表(候选键:
第三范式
第三范式(3NF):满足 2NF,并且所有非主属性都不传递函数依赖于候选键。
-
示例:
原始表(候选键:StudentID
):StudentID Name Dept Dean S001 张三 计算机 李老师 问题:
StudentID → Dept → Dean
,形成传递依赖。
分解后:- 学生表:
StudentID Name Dept S001 张三 计算机 - 院系表:
Dept Dean 计算机 李老师
- 学生表:
BCNF范式
BC 范式(BCNF):满足 3NF,并且对于每个函数依赖 X→Y,X 必须是超键。
-
示例:
原始表(候选键:(Student, Course)
和(Course, Teacher)
):Student Course Teacher 张三 数学 王老师 李四 数学 王老师 问题:
Course → Teacher
(主属性Teacher
依赖候选键的一部分Course
)。
分解后:- 选课表:
Student Course 张三 数学 - 课程教师表:
Course Teacher 数学 王老师
- 选课表: