文章目录
数据库范式(如何拆分3NF的表)
分类
- 1.第一范式(1NF):每一列都是不可分割的原子数据项
- 2.第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF的基础上消除非主属性对主码 的部分函数依赖)
- 3.第三范式(3NF) :在2NF的基础上,任何非主属性不依赖于其他非主属性(在2NF的基础上消除传递依赖)
- 4.巴斯-科德范式(BCNF)
- 5.第四范式(4NF)
- 6.第五范式(5NF,又称完美范式)
第一范式
概念
如上表所示,“系”这一列双可以拆分成“系名”和“系主任”两个子列,所以这个表格不遵循1NF(每一列都是不可分割的原子项)
上表遵循第一范式
第一范式存在的问题
- 1.存在非常严重的数据冗余(重复):姓名、系名、系主任
- 2.数据添加存在问题:添加新开设的系和系主任时数据不合法
- 3.数据删除存在问题:删除张三,其后的系名、系主任也被删除
第二范式
在1NF的基础上,非码属性必须完全依赖于候选码(在1NF的基础上消除非主属性对主码的部分函数依赖)
几个概念
1.函数依赖
A–>B:如果通过A属性(或属性组)的值,可以唯一确定B属性的值,那么就称B依赖于A
例如:学号–>姓名 (学号,课程名称)–> 分数
2.完全函数依赖
A–>B:如果A是一个属性组,则B属性值的确定需依赖于A属性组中所有的属性值
例如:(学号,课程名称)–> 分数
3.部分函数依赖
A–>B:如果A是一个属性组,则B属性值的确定需依赖于A属性组中部分的属性值
例如:(学号,课程名称)–> 姓名,其实学号就可以确定姓名
4.传递函数依赖
A–>B, B–>C:如果通过A属性(或属性组)的值,可以唯一确定B属性的值;再通过B属性(或属性组)的值,可以唯一确定C属性的值,则称C传递依赖于A
例如:学号 --> 系名,系名–>系主任
5.码
如果在一张表中,一个属性或属性组被其它所有属性所完全依赖,则称这个属性或属性组为该表的码
在一个表中选出最少的列,这些列可以推导出其他所有的列,那么这些列组成的就是码!
例如在上表中码为(学号,课程名称)
- 1.主属性:码属性组中的所有属性
- 2.非主属性:除码属性组外的所有属性
创建符合2NF的表
在1NF表 (学号,课程名称) 为码,所以学号和课程名称都是主属性,其他的为非主属性,而姓名、系名以及系主任部分依赖于(学号,课程名称)。
2NF的作用就是在1NF的基础上消除非主属性对主属性的部分函数依赖,所以可以将1NF的表拆分成选课表和学生表。
2NF只解决了部分依赖问题,即消除了1NF中的数据冗余问题
第二范式存在的问题
- 1.数据添加存在问题:添加新开设的系和系主任时数据不合法
- 2.数据删除存在问题:删除张三,其后的系名、系主任也被删除
第三范式
在2NF的基础上,任何非主属性不依赖于其他非主属性(在2NF的基础上消除传递依赖)
在2NF的学生表中,存在学号–>系名,系名–>系主任的传递依赖,3NF的工作就是消除2NF中的传递依赖
第三范式解决了第二范式中仍存在的数据添加问题和数据删除问题
总结(个人理解)
如何拆分表,使其符合3NF?
1.将符合1NF的表拆分成符合2NF的表。(即消除1NF表中的部分依赖问题)
步骤:①在符合1NF的表中选出最少的列,通过这些列可以推导出其他所有的列。
例如,最初我们只选择“学号”列:学号–>姓名(完全依赖)、学号–>系名(完全依赖)、学号–>系主任(完全依赖),但是学号 !–> 课程名称、学号 !–> 课程名称。
所以我们就在“学号”列的基础上再加上“姓名”列:(学号,姓名)–>系名(部分依赖)、(学号,姓名)–>系主任(部分依赖)、但是(学号,姓名) !–> 课程名称、(学号,姓名) !–> 课程名称
同理,(学号、系名)和(学号、系主任)都无法推导出课程名称和分数。
直到我们尝试到(学号,课程名称)时才发现:(学号,课程名称)–>姓名(部分依赖)、(学号,课程名称)–>系名(部分依赖)、(学号,课程名称)–>系主任(部分依赖)、(学号,课程名称)–>分数(完全依赖)。所以(学号,课程名称)就是我们选定的最少的列,这里(学号、课程名称)应该叫做候选码吧?
②根据上一步推导出的依赖关系,我们选取对(学号、课程名称)是完全依赖的原子列–“分数”,它们三列组成一个新表。
③将其他的所有列先暂时组成一个表
④对这个暂时的表重复步骤①
即,首先选定“学号”列,然后通过“学号”列是否可以推导出其他列:学号–>姓名(完全依赖)、学号–>系名(完全依赖)、学号–>系主任(完全依赖),所以“学号”列就是候选码。这个暂时的表也是符合第二范式的。
2.将符合2NF的表拆分成符合3NF的表。(即消除2NF表中的传递依赖)
步骤:①首先检查2NF的两个表是否存在传递依赖
首先看第一张表:学号 !–> 课程名称,课程名称 !–> 分数。所以第一张表不存在传递依赖
再看第二张表:∵学号 –> 系名、系名 –> 系主任
∴学号 –> 系主任(传递依赖)
②将传递依赖的部分再拆成一个表