Java深度学习系列——数据库的三大范式

大家好,我是张哲,是一位在互联网上不愿透露姓名的小学员。

概念:
   在设计数据库的基础上会存在各种各样的问题,因此有些专门的设计规则来避免一些问题,这些设计规则被统称为范式(NF)。
   目前关系数据库中有六大范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF)。
下面我将会针对一张表用范式一层一层的分离

Java深度学习系列——数据库的三大范式_第1张图片

分类:

1、第一范式:保证数据是最小原子项。每一份数据都是不可在分的。
我们先看系这一项,很明显,系可以继续分两项:系名和系主任。
Java深度学习系列——数据库的三大范式_第2张图片

此时我们会发现这么几个问题:

数据冗余:学号、姓名、系名、系主任重复的数据太多,这就会带来两个影响:
浪费存储空间。
更新异常:我们如果将张三丰修改为:张俩丰,则必须将所有的张三丰修改为张俩丰,一个字:麻烦。额,好像是两个字哈哈
数据添加时存在问题:比如仅仅是新添加个系名和系主任,但正常情况下:学号、姓名是不为NULL的,所以就无法之添加系名和系主任会导致数据不合法。
数据删除时存在问题:比如张无忌同学毕业了,把他的数据删掉会导致系名、系主任、课程名称都被删掉。此操作不合理。

2、第二范式:在第一范式的基础上令表中的数据完全依赖于主属性。
这里我们要明白5个概念:
函数依赖:A --> B 通过A属性(属性组)的值可以确定B属性的唯一的值
举例:通过学号可以确定唯一的姓名,通过学号+课程名称可以确定唯一的分数。
完全函数依赖:A --> B 通过A属性组的所有值才可以确定B属性的唯一的值
举例:通过学号+课程名称可以确定唯一的分数。
部分函数依赖:A --> B 通过A属性组中的某些属性值就可以确定B属性的唯一的值
举例:通过学号+课程名称的学号就可以确定唯一的姓名。
传递函数依赖:A --> B ,B --> C 通过A属性(属性组)的值可以确定唯一的B属性的值,再通过确定的B属性的值可以确定唯一的C属性的值。
举例:通过学号可以确定唯一的系名,在通过系名可以确定唯一的系主任是谁。
码:一张表中,某属性(属性组)的数据被其他列的数据完全依赖,则称此属性(属性组)为候选码,简称:码,该表中的码为:学号+课程名称。
主属性:码中的所有属性
非主属性:除了码中属性组中的所有属性。
关于第二范式百度的解释:非码属性必须完全依赖于候选码,实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是在第一范式的基础上属性完全依赖于主键。

  • 分析:要做到非主属性必须完全依赖于主属性。此时表中主属性为:学号+课程名称。则分数是完全依赖于主属性的,而姓名、系名、系主任是部分依赖于主属性的,因此按着第二范式的规则要将姓名、系名、系主任分离出去。

按着第二范式的要求给它分离成两张表:
Java深度学习系列——数据库的三大范式_第3张图片Java深度学习系列——数据库的三大范式_第4张图片

我们再去回想一下之前第一范式遇到的问题:
数据冗余、数据添加时存在问题、数据删除时存在问题。
我按着第二范式分离之后发现:数据已经冗余的负面问题了。但是当数据添加时比如:仅仅是添加一个系名和系主任还会有姓名必须不为NULL的不合法问题。当删除数据时:张无忌毕业了,删除它的数据则会连带着系名跟系主任一同删除。此操作还是不合理。

3、第三范式:在第二范式的基础上更近一层,确保每个属性和主属性都直接相关,而不是间接相关。
分析:姓名和系名是直接相关的,系名和系主任是直接相关的,但是姓名和系主任是间接相关的。因此就有了第三张表。

Java深度学习系列——数据库的三大范式_第5张图片Java深度学习系列——数据库的三大范式_第6张图片
在这里插入图片描述

此时继续来看第二范式没解决的添加数据和删除数据的问题:添加数据时:添加系名和系主任此时不会在影响到学员的姓名,删除数据时:张无忌毕业了,删除它的数据时并不会将系名+系主任删除。

总结:

第一范式是为了保证每个数据项都是不可分割的最小原子项。
第二范式是为了在第一范式的基础上消除部分函数依赖。
第三范式是为了在第二范式的基础上消除传递依赖。
数据库设计时虽然有六大范式,但只要满足前三个范式我们的数据库设计就会非常的合理。

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