数据库范式理论是数据库设计的重要基础,通过范式的应用,可以减少数据冗余,提高数据一致性,简化数据插入、更新和删除操作的复杂性。本文将详细介绍码(主键码和候选码)以及数据库的三大范式(1NF、2NF、3NF),并通过举例说明如何应用这些概念来优化数据库设计。
码
在关系数据库中,码是指能够唯一标识一行数据的列或列的组合。码主要分为候选码和主键码。
候选码
候选码是能够唯一标识一行数据的列或列的组合,具有以下两个特性:
- 唯一性:候选码的值在表中必须是唯一的,即不允许重复值。
- 最小性:不能从候选码中移除任何列而仍然保持唯一性。
例如,在一个学生信息表中,可以有学号、身份证号、手机号、邮箱作为候选码。这些列单独或组合在一起都能够唯一标识一行数据。
主键码
主键码是候选码中的一个,一个表可能有多个候选码,可以从中选择一个作为主键码。主键码在数据库表中必须唯一且不为空,用于唯一标识表中的每一行数据。
例如,在学生信息表中,学号、身份证号、手机号、邮箱都是候选码,可以选择其中的一个作为主键码。假设选择学号作为主键码,那么学号就成了该表的主键,用于唯一标识每个学生的信息。
数据库范式
数据库范式是用于规范数据库设计的规则,通过将数据库设计成符合不同范式的形式,可以减少数据冗余,提高数据一致性,简化数据操作。常见的范式有第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。
第一范式(1NF)
第一范式(1NF)的要求是列的原子性,即表中的每一列都是不可再分的基本数据项,不能包含重复的组或数组。
举例
假设有一个学生信息表,包含以下列:
学号 | 姓名 | 地址 | 课程 |
---|---|---|---|
1 | 张三 | 北京市朝阳区 | 数学,英语 |
2 | 李四 | 上海市浦东新区 | 物理,化学 |
这里的地址包含省市区详细信息,课程列包含了多个课程,这样的设计不符合1NF,因为地址和课程都不是原子性的。
为了符合1NF,需要将地址和课程拆分成独立的列:
学号 | 姓名 | 省 | 市 | 区 | 课程 |
---|---|---|---|---|---|
1 | 张三 | 北京 | 北京 | 朝阳 | 数学 |
1 | 张三 | 北京 | 北京 | 朝阳 | 英语 |
2 | 李四 | 上海 | 上海 | 浦东 | 物理 |
2 | 李四 | 上海 | 上海 | 浦东 | 化学 |
第二范式(2NF)
第二范式(2NF)是在1NF的基础上,要求非码属性必须完全依赖于候选码,消除了非主属性对主码的部分依赖关系。
举例
假设有一个学生课程信息表,包含以下列:
学号 | 课程编号 | 课程分数 | 代课老师 |
---|---|---|---|
1 | C101 | 85 | 张老师 |
1 | C102 | 90 | 李老师 |
2 | C101 | 78 | 张老师 |
2 | C103 | 88 | 王老师 |
这里的码是学号和课程编号的组合(学号+课程编号)。主属性是学号和课程编号,非码属性是课程分数和代课老师。
(学号,课程编号) -> 课程分数,非码属性课程分数
完全依赖于候选码学号+课程编号
。
但是,(课程编号) -> 代课老师,非码属性代课老师
部分依赖于候选码学号+课程编号
。
因此,这个表不符合2NF,因为代课老师
部分依赖于候选码。
为了符合2NF,需要将代课老师拆分到另一个表中:
学生课程信息表:
学号 | 课程编号 | 课程分数 |
---|---|---|
1 | C101 | 85 |
1 | C102 | 90 |
2 | C101 | 78 |
2 | C103 | 88 |
课程信息表:
课程编号 | 代课老师 |
---|---|
C101 | 张老师 |
C102 | 李老师 |
C103 | 王老师 |
第三范式(3NF)
第三范式(3NF)是在2NF的基础上,要求任何非主属性不依赖于其他非主属性,消除了传递依赖。
举例
假设有一个学生信息表,包含以下列:
学号(主键) | 姓名 | 所在系(系主键) | 系地址 |
---|---|---|---|
1 | 张三 | CS | 北京 |
2 | 李四 | EE | 上海 |
候选码是学号,主属性(主键码)是学号,非主属性是姓名、所在系和系地址。
满足1NF:列都具有原子性。
满足2NF:主属性只有一个,因此不存在部分依赖关系。
不满足3NF:非主属性系地址
依赖于非主属性所在系
,存在传递依赖。
为了符合3NF,需要将系地址拆分到另一个表中:
学生信息表:
学号 | 姓名 | 所在系 |
---|---|---|
1 | 张三 | CS |
2 | 李四 | EE |
系信息表:
系主键 | 系地址 |
---|---|
CS | 北京 |
EE | 上海 |
通过拆分表,消除了非主属性之间的依赖关系,确保了每个非主属性都只依赖于主属性。
范式优化的综合实例
为了更好地理解范式的应用,下面通过一个综合实例来展示如何从1NF优化到3NF。
初始设计(不符合范式)
假设有一个学生选课系统,包含以下信息:
学号 | 姓名 | 电话 | 课程编号 | 课程名称 | 分数 | 老师姓名 | 老师电话 |
---|---|---|---|---|---|---|---|
1 | 张三 | 123456 | C101 | 数学 | 85 | 王老师 | 654321 |
1 | 张三 | 123456 | C102 | 英语 | 90 | 李老师 | 987654 |
2 | 李四 | 234567 | C101 | 数学 | 78 | 王老师 | 654321 |
2 | 李四 | 234567 | C103 | 物理 | 88 | 张老师 | 321654 |
这张表包含了学生信息、课程信息和老师信息,存在大量的冗余数据,不符合任何范式。
符合1NF
首先,确保每一列都是原子性的,将表设计成以下形式:
学号 | 姓名 | 电话 | 课程编号 | 课程名称 | 分数 | 老师姓名 | 老师电话 |
---|---|---|---|---|---|---|---|
1 | 张三 | 123456 | C101 | 数学 | 85 | 王老师 | 654321 |
1 | 张三 | 123456 | C102 | 英语 | 90 | 李老师 | 987654 |
2 | 李四 | 234567 | C101 | 数学 | 78 | 王老师 | 654321 |
2 | 李四 | 234567 | C103 | 物理 | 88 | 张老师 | 321654 |
这里已经满足了1NF,所有列都是原子性的。
符合2NF
其次,消除非主属性对主码的部分依赖,确保所有非码属性完全依赖于候选码。将表分成学生信息表、课程信息表和学生课程关系表:
学生信息表:
学号 | 姓名 | 电话 |
---|---|---|
1 | 张三 | 123456 |
2 | 李四 | 234567 |
课程信息表:
课程编号 | 课程名称 | 老师姓名 | 老师电话 |
---|---|---|---|
C101 | 数学 | 王老师 | 654321 |
C102 | 英语 | 李老师 | 987654 |
C103 | 物理 | 张老师 | 321654 |
学生课程关系表:
学号 | 课程编号 | 分数 |
---|---|---|
1 | C101 | 85 |
1 | C102 | 90 |
2 | C101 | 78 |
2 | C103 | 88 |
符合3NF
最后,消除非主属性对其他非主属性的依赖,确保非主属性只依赖于主属性。这里,老师的电话依赖于老师姓名,而老师姓名又依赖于课程编号,这里存在传递依赖。
课程信息表:
课程编号 | 课程名称 | 老师编号 |
---|---|---|
C101 | 数学 | T1 |
C102 | 英语 | T2 |
C103 | 物理 | T3 |
老师信息表:
老师编号 | 老师姓名 | 老师电话 |
---|---|---|
T1 | 王老师 | 654321 |
T2 | 李老师 | 987654 |
T3 | 张老师 | 321654 |
学生课程关系表:
学号 | 课程编号 | 分数 |
---|---|---|
1 | C101 | 85 |
1 | C102 | 90 |
2 | C101 | 78 |
2 | C103 | 88 |
通过这种拆分,消除了非主属性之间的依赖,确保所有非主属性都只依赖于主属性,达到了3NF的要求。
结论
通过本文的详细介绍,可以看出数据库范式是规范数据库设计的重要工具。通过理解和应用候选码、主键码以及三大范式,可以有效减少数据冗余,提高数据一致性,简化数据操作。在实际的数据库设计过程中,合理应用这些理论,能够大大提高数据库系统的性能和可维护性。