数据库学习--范式详细理解

文章目录

    • 写在前面
    • 关系型数据库面临的问题
    • 函数依赖
    • 范式理解
    • 总结及注意事项

写在前面

本文主要写写数据库设计,核心点在于范式的理解。
本文是复习与总结我本科时上课所学和自己的理解,感谢当时老师的辛苦教学。
这篇博客主要根据我下面的例子展开,先介绍问题,然后铺垫基础知识,之后引出范式,解决问题。

关系型数据库面临的问题

在我们只考虑函数函数依赖这一数据依赖时,会存在几个问题。
下图是一个很有问题的数据库设计,我们就以这个来分析问题,展开范式的学习。
数据库学习--范式详细理解_第1张图片

  • 数据冗余:我们用上面在这幅图中,我们的南波兔每上一门课,我们的表中就多一条记录,重复记录了学生id、学生姓名、课程教师这些信息,这是没有必要的。
  • 更新异常:当我们对上面的表进行操作,假设英语课程的老师换成了其他的老师,则需要把所有英语课程的老师姓名更改,如果有一个没改,就会异常
  • 插入异常:如果我们此时新增加一门课,比如体育,但此时还没有人选课,则,这门课怎么放进去呢,我是以学生id为主码的,主码不能为空,那么此时就会出现矛盾。
  • 删除异常:如果南波兔毕业了,那我们也没有必要再留着南波兔的信息了吧,此时要删除南波兔的信息,一并也把课程,课程教师,寝室信息也都给删除了,然而寝室,课程这些信息我们都要留着的,不应删除,那这就是问题。

因为存在着上面这些问题,所以这中数据库设计是不合理的,所以,我们需要对其进行改进,在改进之前,我们先分析这个关系数据中存在依赖。

函数依赖

从上图中,我们根据常识,(也是为了更好的讲解范式)定下这些依赖关系:

  • (学生id)->(学生姓名);
  • (课程教师)->(课程)(这里我们就假设一个课程就一个课程老师,即一一对应关系。学校小嘛,我以前去支教的山区小学2个老师带60多学生的所有课程呢);
  • (学生id)->(寝室id)->(宿舍楼);
  • (学生id,课程)->(课程分数)

这里,我们根据这些来找找主键。
从学生id出发,可以到学生姓名,寝室id,宿舍楼;从课程出发可以到课程教师;从学生id与课程出发,可以到课程分数。而学生id并不能决定课程具体是哪个,所以这里学生id与课程是候选码,所以我们认为他们是主键
我们来一一归类:

  • 部分依赖:例如(学生id,课程)->(寝室id),明明学生id一个就能确定寝室id,把学生姓名去掉也行
  • 完全依赖:(学生id,课程)->(课程分数),这里学生id与课程都是缺一不可
  • 传递依赖:(学生id)->(寝室id)->(宿舍楼)是个明显的例子,宿舍楼依赖于寝室id,寝室id依赖于学生id,从而导致宿舍楼传递依赖于学生id。

范式理解

满足特定要求的模式,作为衡量一个关系模式好坏的标准。当我们关系型数据库设计的范式的级别越来越高,则说明我们的设计越好,出现的一开始我们讲到的问题越少。
范式之间的关系:
在这里插入图片描述
可以看出,高级别范式是包含于低级别范式的。

第一范式

一个关系模式的所有属性都是不可分的基本数据项,那么就属于第一范式。
其实也就是我们的每一列不能再往下细分,比如电话可以分为手机与座机,那这种一旦出现就是不满足第一范式的。
我们上面的例子是满足第一范式的。

第二范式

在第一范式的基础上,每一非主属性完全函数依赖于主属性。
也就是说这个数据库中不存在部分依赖。我们用上面南波兔的例子。
这里我们画出示意图。
数据库学习--范式详细理解_第2张图片
可以看到是
(学生id,课程)->(寝室id)(课程,学生id)->课程教师是部分依赖。
所以这里消除这个依赖。我们把学生id与课程拆分开,同时不损失依赖(保留二者同时存在的信息),就可以达到第二范式。
结果是这样:
数据库学习--范式详细理解_第3张图片

第三范式

这里,我们对第三范式概括为,符合第二范式,且,消除非主属性对主码的传递依赖。
由上面满足第二范式的示意图可以看到,明显,只有宿舍楼是满足传递依赖于学生id的,所以这里我们要把这个传递依赖的关系给拆分开。
拆分结果如下图所示。
数据库学习--范式详细理解_第4张图片
至此,我们这里的设计满足了第三范式。

第四范式

第四范式可以概括为:满足第三范式的基础上,消除表中的多值依赖。
这里,因为我们的例子中没有多值依赖(实际上是我没有想出来包含所有这里用到依赖的例子hah,老实说,做老师备课还真挺麻烦,不光要会讲,还有会举错例)
这里单独举另外一个例子
数据库学习--范式详细理解_第5张图片
这里,一个职位对应多种权限,这里就是我们的多值依赖了。很明显,我们可以看到一个问题,姓名重复了太多次了,这显然是没有必要的。
所以我们要解除这种依赖,怎么做呢,如下图所示:
数据库学习--范式详细理解_第6张图片
数据库学习--范式详细理解_第7张图片
如上,就是解除多值依赖,从而达到第四范式了。

第五范式

第五范式是在第四范式的基础上做的进一步规范化,处理相互依赖的多值情况,将表分割成尽可能小的块,为了排除在表中所有的冗余
第五范式实际用到的非常少,基本到第三,第四范式就ok,所以这里就不赘述。

总结及注意事项

其实,把整个文章看下来,范式(老是想打成范数,学矩阵的后遗症hah)就是对关系型数据库的一种衡量标准,范式级别越高,要求越高,数据库出现问题越少。而提高范式级别,就是要解除掉多余的依赖,我们解除依赖的方法呢就是拆分关系。
但一定要注意,这里是拆分关系,而不是删除关系,关系拆分之后,还是能像原来那样回推出完整的逻辑。
举个例子,我们解除传递依赖x->y->z,这里的正确做法是x->y,y->z,我们对拆分的关系回推,x决定y,y决定z,那不就是x决定z嘛,这里的关系并没有丢失。而如果我们拆分成x->y,x->z,此时我们就丢掉了y->z这一关系了。所以一定要注意,拆分关系,所有的关系不能损失。
现实点拆分关系可以理解成,一张冗余多毛病的表,我们给拆分成多张表,各表之间通过外键啥的连接。

你可能感兴趣的:(数据库学习)