数据库设计的三大范式

范式的概念:
指的是设计数据库时需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求。

设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。

分类:

第一范式(1NF)

要求: 每一列都是不可分割的原子数据项。
如下是一张学生信息表:
数据库设计的三大范式_第1张图片
显然“系”这一列可以拆分,所以这张表不符合第一范式。
修改之后使之符合第一范式:
数据库设计的三大范式_第2张图片
然而,现在这张表依然存在很多问题:
1.存在非常严重的数据冗余(重复):姓名、系名、系主任
2.数据添加存在问题:添加新开设的系和系主任时,数据不合法
在这里插入图片描述
3.数据删除存在问题:张无忌同学毕业了,删除数据,会将系的数据一起删除。
数据库设计的三大范式_第3张图片
要想解决以上的问题,就需要第二范式了。

第二范式(2NF)

要求: 在1NF的基础上,非主属性必须完全依赖于码(即在1NF基础上消除非主属性对主码的部分函数依赖)。
是不是有些看不懂?要想搞清楚第二范式,必须先了解几个简单概念——

1.依赖
若有两个属性,A–>B,如果通过A属性(属性组)的值,可以确定唯一B属性的值,则称B依赖于A。(依赖全称“函数依赖”,此处即下文都省略“函数”,简称xx依赖。)
例如:学号–>姓名 ; (学号,课程名称) --> 分数

2.完全依赖
A–>B, 如果A是一个属性组,则B属性值的确定,需要依赖于A属性组中所有的属性值,则称B完全依赖于A组
例如:(学号,课程名称) --> 分数

3.部分依赖
A–>B, 如果A是一个属性组,则B属性值的确定,只需要依赖于A属性组中某一些值即可。则称B部分依赖于A组
例如:(学号,课程名称) – > 姓名

4.传递依赖
A -> B, B -> C ;如果通过A属性(属性组)的值,可以确定唯一B属性的值,再通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递依赖于A。
例如:学号–>系名,系名–>系主任

5.
如果在一张表中,一个属性或属性组,被其他所有属性完全依赖,则称这个属性(属性组)为该表的码
例如:下表中的码为(学号,课程名称)
数据库设计的三大范式_第4张图片
由码的概念引出两种属性:

  • 主属性:属性组中的所有属性
  • 非主属性:除了码属性组的其他属性

上面的概念都很简单吧,那么我们用人话把第二范式再说一遍,就是——
表中只有完全依赖,没有部分依赖

我们再观察这张表,可以发现,姓名、系名、系主任这几个非主属性,其实只是部分依赖于(学号,课程名称)的,因为它们只需要根据码中的学号就能确定了,由于存在部分依赖,所以这张表是不符合第二范式的。
那么我们如何修改这张表,使之符合第二范式呢?
先理清楚表中的完全依赖关系:姓名,系名,系主任完全依赖于学号;分数完全依赖于(学号,课程名称)这个码;那么我们根据这两则关系将表拆分为两个表:
数据库设计的三大范式_第5张图片
显然,每一个表都只存在完全依赖的关系了,那么现在这两个表都是符合第二范式的。

回头看之前的三个问题都解决了吗?

1.存在非常严重的数据冗余(重复):姓名、系名、系主任
2.数据添加存在问题:添加新开设的系和系主任时,数据不合法
3.数据删除存在问题:张无忌同学毕业了,删除数据,会将系的数据一起删除。

至此只解决了数据冗余的问题,要解决后俩问题,需要引入第三范式。

第三范式(3NF)

在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)。
显然,上面修改后的学生表中,系主任是通过系名传递依赖于学号的,因此还不符合第三范式。
要继续修改学生表,使之符合第三范式,只需要再拆分出一张表,让系主任完全依赖于系名即可。
数据库设计的三大范式_第6张图片
如上,这三张表都不存在传递依赖,符合第三范式。
回顾上面留下的两个问题——

2.数据添加存在问题:添加新开设的系和系主任时,数据不合法
3.数据删除存在问题:张无忌同学毕业了,删除数据,会将系的数据一起删除

现在都已经得到了解决!

你可能感兴趣的:(数据库,mysql,数据库)