数据库的范式

发布于 12 天前  19 次阅读


首先,在开始这篇文章之前,我们要理解什么是数据库的范式。简单来说,是设计数据库的一种基本理念。目前数据库最主要有着以下几种范式:

第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。

以上范式中,越靠近后面的要求越高。合理使用数据库范式,可以建立冗余较小、结构合理的数据库。但是也不能一味的去按照范式来设计数据库。应结合实际需求来进行数据库的设计。

由于常用的数据库设计采用的是前三种范式。故本文只对前三种范式进行讨论。

我们先来贴出三大范式的主要内容:

第一范式:数据库表的每一列都是不可分割的原子数据项

第二范式:在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第三范式:在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

上面涉及到某些概念,将在后文进行阐述。

为了方便理解。我们先建立了一张表:

数据库的范式

如上表,是一张关于大学信息的表。当然,这张表是不符合任何范式的规范的。首先,按照第一范式的要求。我们在数据库设计的过程中,不能存在可分割的原子数据项(即子列)。其中,系内容中的系名和课程名即为子列,所以并不符合第一范式的规范。

所以在建立数据库表的过程中,我们要将系名和课程名单独分为一个列。如下图:

数据库的范式

这样的数据库设计似乎就满足了第一范式的要求了。那么,我们来分析一下,第一范式所存在的问题:

  1. 存在严重的数据冗余。
  2. 数据添加时,可能造成数据不合法。如,添加新系时,其他数据为null并不合法
  3. 数据删除时,可能会删除无关数据。如,删除某位同学的数据时,会将系的数据一起删除。

鉴于以上存在的问题,我们来讨论第二范式。注:第一范式是数据库设计的基础

在开始之前,我们先来理清几个概念:

  1. 函数依赖:如果通过A的属性值,可以确定唯一的一个B属性值,这B依赖于A,AB之间存在函数依赖。
  2. 完全函数依赖:如果非主属性B函数依赖于构成某个候选关键字的一组主属性A,这称B完全依赖于A。例如上表中。主属性学号和课程名能确定一个唯一的分数。则被完全依赖。
  3. 部分依赖:完全依赖相对应,之间存在着部分依赖关系。
  4. 码:一张表中,一个属性或属性组被其他所有属性完全依赖,这称之为码。分主码(主键)和候选码
  5. 主属性:包含在任一候选关键字中的属性称主属性。
  6. 非主属性:与主属性相对。例如:在关系——学生(学号,姓名,年龄,性别,班级)中,主码是“学号”,那么其他的“姓名”、“年龄”、“性别”、“班级”就都可以称为非主属性。

在理解了如上概念之后,我们来对第二范式进行理解。

在第一范式的基础上消除非主属性对主码部分函数依赖。

什么意思呢?如表中:

学号和课程名称成为码,分数完全依赖于码,构成完全依赖,而姓名,系名,系主任构成部分依赖。

数据库的范式

那如何消除呢?在此我们要将其拆分为两个表。

数据库的范式

分为如上两个表,在左表中,前两个为码(主属性),分数是非主属性完全依赖于主属性。右表中,学号为码。其他三个属性依赖于学号。

索引就可以对第二张表的数据进行精简。(临时发现一个错误,改了下名)

这样我们就完成了消除非主属性对主码部分的函数依赖了(姓名,系名,系主任)

数据库的范式

这样我们来看第一范式存在的问题。

数据库的范式

这样第一个问题就被解决了,但是似乎后面两个问题还是仍然存在。

这时候就需要第三范式的介入:

在第二范式中消除传递依赖。

如在表中:

数据库的范式

学号被系名依赖,系主任被系名依赖,这样系主任就传递依赖于学号了。

要消除传递依赖,则需要再分一张表。

数据库的范式

现在在拆分后的表中,学号是主属性(码),姓名和系名依赖于学号,这样就消除了传递依赖。

在右表中。系名是主属性,系主任依赖于系名。

这样创建的三张表就遵循了第三范式。

数据库的范式

我们接着回到第二范式中存在着的问题。

数据库的范式

添加时:如果要添加新的系,直接在第三张表中添加。系存在但不一定有学生,数据合法。

删除时:删除时,如萌新消失了。删除萌新的数据,系的数据仍然保存,这样删除的问题也解决了。

这样上面所有的问题都被解决掉了。也满足了数据库基本设计的原则。

遵循以上三种范式,能够避免一般数据库数据中存在的问题。也使得数据库的设计更为合理。

当然还是不能一味的去追寻范式。而要根据实际的情况合理的对表进行设计。

 

注:本文编辑时表述是根据本人情况所表述的,如果对某个概念存在问题,请百度。


含词未吐,气若幽兰