首页 > 编程知识 正文

请分析数据库范式1NF、2NF、3NF的区别,数据库3nf例子

时间:2023-05-04 20:47:45 阅读:237737 作者:1119

关系型数据库设计时为确保数据存储规范化,通常需要按照范式设计数据,接下来主要介绍下1NF-3NF递进式数据库设计,4NF、5NF日常使用较少不包含在本次内容中。

首先总体描述下1NF-3NF转化的过程

1NF------------------>2NF  消除非主属性对码的部分函数依赖

2NF------------------>3NF 消除非主属性对码的传递函数依赖

1NF:

1NF是数据库最基本的要求,每个属性不可分割。但如下图可以看到如果仅仅满足1NF会有大量数据冗余,造成数据存储占用大量空间,同时存在插入、修改、删除异常问题。

图-1NF数据

插入异常:新建一个系,但是暂时还没有招收任何学生(比如3月份就新建了,但要等到8月份才招生),无法将系名与系主任的数据单独地添加到数据表中去的

更新异常:假如sxdct转系到法律系,为了保证数据库中数据的一致性,需要修改三条记录中系与系主任的数据

删除异常:某个系中所有学生相关的记录都删除,那么所有系与系主任的数据也就随之消失了(一个系所有学生都没有了,并不表示这个系就没有了)

2NF:

2NF在1NF基础上消除非主属性对码的部分函数依赖,这句话涉及4个概念:“码”、“非主属性”、“部分函数依赖”和“函数依赖”,下面对这些概念进行解读。

码:假设 K 为某表中的一个属性或属性组,若除 K 之外的所有属性都完全函数依赖于 K(这个“完全”不要漏了),那么我们称 K 为候选码,简称为码,即当 K 确定的情况下,该表除 K 之外的所有属性的值也就随之确定,那么 K 就是码,一个表可以有多个码。

如上图1NF中,码是(学号,课号)。通过学号可以确认姓名、院系、主任名称。学号和课名可以确定成绩。

非主属性:除去所有的主属性,剩下的就都是非主属性

函数依赖:在一张表中如果属性x的值确定,那么属性y的值也就确定下来了,可以说属性y函数依赖x,即x——>y,y=f(x)。比如:上图中一个学号唯一对应一个姓名,则可以说姓名依赖与学号,但反过来就不对,因为姓名有重名的可能,这样一个姓名可能对应多个学号,即学号——>姓名。还有学号——>系号,系号——>系主任。

对函数依赖进行细分后可以划分为三大类,分别是:

安全函数依赖:在一张表中,若 X → Y,且对于 X 的任何一个真子集(假如属性组 X 包含超过一个属性的话),X ' → Y 不成立,那么我们称 Y 对于 X 完全函数依赖,记作 X F→ Y。比如:(学号,课名) F→ 分数 ,通过学号无法确定分数,通过课名也无法确定分数,只有两者作为一个整体才可以确定分数。

传递函数依赖:假如 Z 函数依赖于 Y,且 Y 函数依赖于 X (严格来说还有一个X 不包含于Y,且 Y 不函数依赖于Z的前提条件),那么我们就称 Z 传递函数依赖于 X ,记作 X T→ Z

部分函数依赖:假如 Y 函数依赖于 X,但同时 Y 并不完全函数依赖于 X,那么我们就称 Y 部分函数依赖于 X,记作 X P→ Y。比如:(学号,课名) P→ 姓名,但姓名也依赖于学号。

数据表结构是否符合2NF的判断方法是:

1、找出数据表中的码。

2、根据码确定主属性。

3、确定非主属性。

4、判断非主属性是否部分依赖于码。

1NF数据梳理的函数依赖关系如下:

1NF数据函数依赖关系

对1NF数据应用2NF判断方法确定是否上述表结构是否属于2NF。步骤如下:

第一步:表中对码是(学号、课名)

第二步:主属性是学号、课名

第三步:非主属性是分数、姓名、系名、系主任

第四步:

(学号、课名)——>分数,存在非主属性分数对(学号、课名)的完全依赖,因为只有两者一起才可以确定分数值。

(学号、课名)——>姓名,存在非主属性姓名对(学号、课名)的部分函数依赖,因为学号——>姓名

(学号、课名)——>系名,存在非主属性姓名对(学号、课名)的部分函数依赖,因为学号——>系名。

所以上述数据表结构只属于1NF而不是2NF。那如何将上述表转变为2NF?

按照1NF到2NF的转化过程,需要做的是消除部分函数依赖,那就需要将上面数据表结构拆分成多个数据表。如下拆分方法:

选课(学号,课名,分数)

学生(学号,姓名,系名,系主任)

接下来应用是否为2NF判断方法:

对于选课(学号,课名,分数)表,码是学号、课程,非主属性是分数,分数列完全函数依赖(学号、课名)。

而学生(学号,姓名,系名,系主任)表,码是学号,非主属性是姓名、系名、系主任,因为码只有一个主属性,姓名、系名、系主任完全函数依赖学号。符合2NF规范。

数据拆分后新的函数依赖关系:

图-2NF依赖关系

图-2NF数据表结构

验证是否还存在插入、修改、删除异常问题。

测试:

1、sxdct转系到法律系

只需要修改一次sxdct对应的系的值即可。——有改进

2、数据冗余是否减少了?

学生的姓名、系名与系主任,不再像之前一样重复那么多次了。——有改进

3、删除某个系中所有的学生记录

该系的信息仍然全部丢失。——无改进

4、插入一个尚无学生的新系的信息

因为学生表的码是学号,不能为空,所以此操作不被允许。——无改进

如上可知符合2NF的要求,很多情况下还是不够的,而出现问题的原因,在于仍然存在非主属性系主任对于码学号的传递函数依赖。为了能进一步解决这些问题,还需要将符合2NF要求的数据表改进为符合3NF的要求。

3NF:

在2NF的基础之上,消除了非主属性对于码的传递函数依赖。存在非主属性对于码的传递函数依赖,则不符合3NF的要求。

依据要求判断是否满足3NF。

选课(学号,课名,分数)表,码是(学号、课名),分数完全依赖(学号、课名)。

学生(学号,姓名,系名,系主任)表,码是学号,非主属性为姓名、系名和系主任。因为 学号 → 系名,同时 系名 → 系主任,所以存在非主属性系主任对于码学号的传递。不符合3NF要求。

将2NF中的表进行下一步分解后如下:

选课(学号,课名,分数)

学生(学号,姓名,系名)

系(系名,系主任)

选课表属于完全函数依赖,满足3NF。

学生表码是学号,非主属性是姓名、系名,属于完全函数依赖,满足3NF。

系表,码为系名,主属性为系名,非主属性为系主任,属于完全函数依赖,满足3NF。

图-3NF函数依赖

图-3NF数据表

验证是否存在之前插入、修改、删除异常问题。

1、删除某个系中所有的学生记录

该系的信息不会丢失。——有改进

2、插入一个尚无学生的新系的信息。

因为系表与学生表目前是独立的两张表,所以不影响。——有改进

3、数据冗余更加少了。——有改进

结论

由此可见,符合3NF要求的数据库设计,基本上解决了数据冗余过大,插入异常,修改异常,删除异常的问题。当然,在实际中,往往为了性能上或者应对扩展的需要,经常做到2NF或者1NF。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。