目录
数据库范式理论是为了设计出高效、冗余度低、结构合理的数据库而建立的一系列规则和标准,主要用于规范化数据库表结构,以减少数据冗余,提高数据的一致性和完整性。常见的范式有第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、BC 范式(BCNF)等。
-
第一范式(1NF)
- 定义:要求数据库表中的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。
- 举例:假设有一个“学生信息表”,其中有“学生姓名”、“课程名称”、“成绩”等列。如果“课程名称”列中存储了多个课程名,如“数学,英语,物理”,这就不符合1NF。
不满足1NF的情况:
正确的做法:
将“课程名称”列拆分成多个列,或者将每个学生的每门课程成绩作为一条独立的记录存储。
-
第二范式(2NF)
- 定义:在满足第一范式的基础上,要求表中的每个候选码(可以理解为主键)都能唯一确定一行,并且每一个非主属性完全依赖于主键,而不能只依赖于主键的一部分。
- 举例:假设有“订单明细表”,包含“订单编号”、“商品编号”、“商品名称”、“商品价格”、“数量”等列,其中“订单编号”和“商品编号”共同构成主键。“商品名称”和“商品价格”只依赖于“商品编号”,而不是整个主键,这就不满足2NF。
不满足2NF的情况:
正确的做法:
将“商品名称”和“商品价格”等与商品相关的信息提取出来,单独创建一个“商品表”,“订单明细表”中只保留“订单编号”、“商品编号”和“数量”等与订单直接相关的信息,通过“商品编号”与“商品表”建立关联。
商品表:
订单明细表:
-
第三范式(3NF)
- 定义:在满足第二范式的基础上,要求表中的每一个非主属性不传递依赖于主键。即不存在非主属性之间的函数依赖关系。
- 举例:假设在“员工信息表”中,有“员工编号”、“员工姓名”、“部门编号”、“部门名称”等列,“员工编号”是主键。“部门名称”依赖于“部门编号”,而“部门编号”又依赖于“员工编号”,这就存在传递依赖,不符合3NF。
不满足3NF的情况:
正确的做法:
将“部门编号”和“部门名称”提取出来,创建“部门表”,“员工信息表”中只保留“员工编号”、“员工姓名”和“部门编号”,通过“部门编号”与“部门表”关联。
部门表:
员工信息表:
-
BCNF范式(Boyce-Codd范式)
- 定义:是对3NF中的一些特殊情况的规范,可以理解为加强版的3NF。BCNF要求每个表只有一个候选键,同时所有列都要消除部分依赖和传递依赖,主属性也要消除部分依赖和传递依赖。
- 举例1:有关系模式R(A,B,C,D,E),假设说A,B,C都是主属性,其中A+B或者BC都可以作为主码使用,那么,如果A+B为主码时,C如果不安全依赖于A和B(比如说C只依赖于A,而不依赖于B),那么该关系模式就不符合BCNF范式。
- 举例2:假设有课程安排表,该表中有列“学生编号”、“教师编号”、“课程编号”、“上课时间”、“上课地点”),其中列“学生编号”、“教师编号”、“课程编号”可唯一确定一行,也就是说这三列都是主属性,并且任意两列的组合都可作为主码(主键)使用,那么,如果“学生编号”+“教师编号”为主码时,如果“课程编号”不完全依赖于主码,而是依赖于“学生编号”(或“课程编号”)中的一个,那么该关系模式就不符合BCNF范式。正确的做法是把“课程编号”提取出来,与“学生编号”共同组成一个新表。
不满足BCNF的情况:
原始课程表:
正确的做法:
将原始表拆分为两个表。
表1:学生-教师-上课信息
表2:学生-课程信息
通过遵循这些范式,可以帮助我们设计出更加规范化的数据库结构,减少数据冗余并提高数据一致性。但在实际软件开发过程中需要综合考虑多方面因素,包括但不限于性能、可扩展性、维护成本等。因此,并非所有情况下都需要严格遵守范式理论,关键在于找到适合当前项目特点的设计方案。理解范式原理并在必要时灵活运用它们,将有助于做出更明智的技术决策。