数据库设计范式

数据库设计范式详解

简介

设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。

 满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。

 前言

数据库范式是数据库设计中必不可少的知识,没有对范式的理解,就无法设计出高效率、优雅的数据库,甚至设计出错误的数据库。

而想要理解并掌握范式却并不是那么容易。教科书中一般以关系代数的方法来解释数据库范式。这样做虽然能够十分准确的表达数据库范式,但比较抽象,不太直观,不便于理解,更难以记忆。

 本文用较为直白的语言介绍数据库设计的范式概念,以便于理解和记忆,可能表达上有些不精确。但对于初学者应该是个不错的入门,话不多说开撸。

概念

1、什么是范式(NF)?

按照教材中的定义,范式是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度”。

简单的理解为:一张数据表的表结构所符合的某种设计标准的级别数据库范式也分为1NF,2NF,3NF,BCNF,4NF,5NF。一般在我们设计关系型数据库的时候,最多考虑到BCNF就够。

2、什么是关系型数据库,非关系型数据库?

关系型数据库
采用了关系模型来组织数据的,简单来说,就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
常见的关系型数据库:Oracle、DB2、PostgreSQL、Microsoft SQL Server、Microsoft Access、MySQL。

关系型数据库特点
容易理解:二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解
使用方便:通用的SQL语言使得操作关系型数据库
易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率

非关系型数据库
非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。
非关系型数据库以键值对存储,且结构不固定。
每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对。
不局限于固定的结构,可以减少一些时间和空间的开销。

非关系型数据库特点
提升性能:key-value数据库的主要特点是具有极高的并发读写性能。例如:Redis, Amazon DynamoDB, Memcached,Microsoft Azure Cosmos DB和Hazelcast
快读查询:在海量的数据中可以快速的查询数据。例如:MongoDB,Amazon DynamoDB,Couchbase,Microsoft Azure Cosmos DB和CouchDB
数据搜索:对海量数据进行近实时的处理和分析处理,可用于机器学习和数据挖掘。例如:例如:MongoDB,Amazon DynamoDB,Couchbase,Microsoft Azure Cosmos DB和CouchDB

3、理解一下概念

实体:现实世界中客观存在并可以区分的事物。(例如:一个人,老师与学校的关系,这里说的事物不仅仅是指看的见摸得着的东西,也可以是虚拟的东西。)

属性:实体具有的某一特性。(例如:性别是人的一个属性。在关系型数据库中属性又是一个物理概念,可以看做是表的一列)

元组:表中的每一条记录,也就是每一行。

分量:元组的某个属性。它是一个操作原子,关系型数据库在任何操作的时候,属性是不可分的,否则就不是关系型数据库了。

:关系中的某个属性或者某几个属性的组合。如果这样的码有不止一个,那么大家都叫候选码,我们从候选码中挑一个出来做老大,它就叫主码。

全码:如果一个码中包含了所有的属性,这个码就是全码。

主属性:一个属性只要在任何一个候选码中出现,这个属性就是主属性。

非主属性:与上面相反,没有在任何候选码中出现过,这个属性就是非主属性。

外码:一个属性或者属性组,它不是码,但是别的表的码,它就是外码。

4、范式详解

第一范式(1NF)属性不可分原则

上面已经介绍了属性的概念,我们说它是不可分的。那么它和属性值不可分有什么区别的,下面看一个简单的例子。

例子:

表1
姓名 电话 年龄
小明 15864794485 28
小红 13365468795 010-1234567 29

 

 

 

 

 

在上面的例子中,对于小红属性值的属性电话分成了两个,是可分的。

表2
姓名 电话 年龄
手机 座机
小明 15612345678 010-22222 28
小红 15812345678 010-11111 29

 

 

 

 

 

 

这两种情况都不能满足数据库设计的第一范式,属性不可分的原则。那么正确的做法应该是这样的。

表3
姓名 年龄 手机 座机
小明 28 15612345678  
小红 29 15612345678 010-12345678

 

 

 

 

 

 

我们在这里把电话分成了 手机 和 座机 两个属性。

但是仅仅符合1NF的设计是远远不够的,仍然会存在数据冗余过大,插入异常,删除异常,修改异常的问题。例如表4

表4
学号 姓名 系名 系主任 课程 分数
10001 李明 经济系 大宝 数学 98
10001 李明 经济系 大宝 英语 88
10002 王毅 法律系 付龙 数学 98
10002 王毅 法律系 付龙 语文 89
10003 李丹 英语系  李辰 体育 77

 

 

 

 

 

 

 

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

什么是函数依赖

我们可以这么理解,若果在一张表中属性(或属性组)A 的值确定的情况下,必定能确定属性B的值,那么就可以说B依赖于A,写成 A->B 函数关系表达式 B=F(A);

简单理解为A的值确定的情况下,B的值一定时确定的。在数据表中不存在任意两条记录,A的属性(属性组)上的值相同,而在B的属性上不同。例如学号一样,姓名却不一样的两条记录。

也就是表4中的姓名依赖于学号,写作 姓名->学号 。而不是学号依赖于姓名(名字一样的人很多)。

函数依赖分为三种:

1、完全依赖 

2、部分依赖

3、传递依赖

如果B依赖于A,记做 A->B,而且B不依赖于任何一个A的真子集,则B完全依赖于A,称为完全依赖。例如 姓名完全依赖于学号,记做:学号->姓名,(学号,课程)->分数,分数依赖于属性组,分数对应学号是不成立的,分数对应课程也不成立;

反之如果B能依赖于A的真子集,则称B部分函数依赖于A,称为部分依赖。例如:(学号,课程)->姓名,即学号确定了就能确定姓名,但是课程确定了不能确定姓名;

如果C依赖于B,且B又依赖于A,则称C传递函数依赖于A,称为传递依赖。

子集是一个数学概念:如果集合A的任意一个元素都是集合B的元素,那么集合A称为集合B的子集。

如果集合AB的子集,且AB,即B中至少有一个元素不属于A,那么A就是B的真子集。如图

根据2NF的定义,判断的依据实际上就是看数据表中是否存在非主属性对于码的部分函数依赖
若存在,则数据表最高只符合1NF的要求,若不存在,则符合2NF的要求。
判断方法:
第一步:找出数据表中所有的
第二步:根据第一步所得到的码,找出所有的主属性
第三步:数据表中,除去所有的主属性,剩下的就都是非主属性了。
第四步:查看是否存在非主属性对码的部分函数依赖
表四表示的所有函数依赖关系:

我们得到,表4的码只有一个(学号,课名),主属性有两个学号、课名,非主属性有4个姓名、系名、系主任、分数

对于(学号,课名)-> 姓名,有 学号 ->  姓名,存在非主属性 姓名 对码(学号,课名)的部分函数依赖。
对于(学号,课名) ->  系名,有 学号 ->  系名,存在非主属性 系名 对码(学号,课名)的部分函数依赖。
对于(学号,课名) -> 系主任,有 学号 ->  系主任,存在非主属性 对码(学号,课名)的部分函数依赖。

所以表4存在非主属性对于部分函数依赖,最高只符合1NF的要求,不符合2NF的要求。
为了符合2NF规范要求,我们需要消除这些部分函数依赖,就是将大数据表拆分成多个更小的表。如图
 
对于选课表,其码是(学号,课名),主属性是学号课名。非主属性是分数学号确定,并不能唯一确定分数课名确定,也不能唯一确定分数,所以不存在非主属性分数对于码 (学号,课名)的部分函数依赖,所以此表符合2NF的要求。

对于表4分解后的表为:

表5
学号 课名 分数
10001 数学 98
10001 英语 88
10002 数学 98
10002 语文 89
10003 体育 77

 

 

表6
学号 姓名 系名 系主任
10001 李明 经济系 大宝
10002 王毅 法律系 付龙
10003 李丹 英语系 李辰

 

 

 

 

 

 

 现在如果进行操作看是否存在问题。

1、李明转入法律系,只需要修改一下对应的系的值即可,有改进。

2、数据的冗余减少了,不像之前的重复信息太多,有改进。

3、删除某一个系中所有的学生记录,该系的一些信息会全部丢失,无改进。

4、插入一个新的系,无法插入,无改进。

所以,只单单满足2NF要求是远远不够的,仍然存在非主属性系主任对于码学号的传递函数依赖。

为了能进一步解决这些问题,我们需要将符合2NF要求的数据表改进为符合3NF的要求。那么下面我们看一下什么是3NF。

第三范式(3NF):3NF在2NF的基础之上,消除了非主属性对于码的传递函数依赖

对于选课表,主码为(学号,课名),主属性为学号课名,非主属性只有一个分数,不可能存在传递函数依赖,所以选课表的设计,符合3NF的要求。

对于学生表,主码为学号,主属性为学号,非主属性为姓名系名系主任。因为 学号->系名,同时 系名->系主任,所以存在非主属性系主任对于码学号传递函数依赖,所以学生表的设计,不符合3NF的要求,需要我们去改进。

为了让数据表设计达到3NF的要求,我们必须进一步进行模式分解为以下形式:

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

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

系(系名,系主任)

对于选课表,符合3NF的要求,之前已经分析过了。

对于学生表,码为学号,主属性为学号,非主属性为系名,不可能存在非主属性对于码的传递函数依赖,所以符合3NF的要求。

对于系表,码为系名,主属性为系名,非主属性为系主任,不可能存在非主属性对于码的传递函数依赖(至少要有三个属性才可能存在传递函数依赖关系),所以符合3NF的要求。。

 

 

表6
学号 课名 分数
10001 数学 98
10001 英语 88
10002 数学 98
10002 语文 89
10003 体育 77
表7
学号 姓名 系名
10001 李明 经济系
10002 王毅 法律系
10003 李丹 英语系

 

表8
系名 系主任
经济系 大宝
法律系 付龙
英语系 李辰

现在我们来看一下,进行同样的操作,是否还存在着之前的那些问题?

1、删除某个系中所有的学生记录该系的信息不会丢失。——有改进

2、插入一个尚无学生的新系的信息。因为系表与学生表目前是独立的两张表,所以不影响。——有改进

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

结论

由此可见,符合3NF要求的数据库设计,基本上解决了数据冗余过大,插入异常,修改异常,删除异常的问题。

当然,在实际中往往为了性能上或者应对扩展的需要,经常可以做到2NF或者1NF,但是作为数据库设计人员,至少应该知道,3NF的要求是怎样的。

 BCNF范式(巴斯-科德范式)在3NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)

 巴斯-科德范式(BCNF)是第三范式(3NF)的一个子集,即满足巴斯-科德范式(BCNF)必须满足第三范式(3NF)。

通常情况下,巴斯-科德范式被认为没有新的设计规范加入,只是对第二范式与第三范式中设计规范要求更强,因而被认为是修正第三范式,也就是说,它事实上是对第三范式的修正,使数据库冗余度更小。

这也是BCNF不被称为第四范式的原因。

 BCNF的关系模式有:

1、所有非主属性对每一个码都是完全函数依赖。

2、所有主属性对每一个不包含它的码也是完全函数依赖。

3、没有任何属性完全函数依赖于非码的任何一组属性。

按定义排除了任何属性对码的传递依赖与部分依赖,一般关系型数据库设计中,达到BCNF就可以了!

举例说明:

1、某公司有若干个仓库

2、每个仓库只能有一名管理员,一名管理员只能在一个仓库中工作

3、一个仓库中可以存放多种物品,一种物品也可以存放在不同的仓库中。每种物品在每个仓库中都有对应的数量

已知函数依赖集:仓库名->管理员,管理员->仓库名,(仓库名,物品名)-> 数量
码:(管理员,物品名),(仓库名,物品名)
主属性:仓库名、管理员、物品名
非主属性:数量

不存在非主属性对码的部分函数依赖和传递函数依赖,那么此关系模式是属于3NF的。

然而,这个关系模式是否存在问题呢,下面我来具体分析一下。

1、增加一个仓库,但尚未存放任何物品,是否可以为该仓库指派管理员?——不可以,因为物品名也是主属性,根据实体完整性的要求,主属性不能为空。

2、某仓库被清空后,需要删除所有与这个仓库相关的物品存放记录,会带来什么问题?——仓库本身与管理员的信息也被随之删除了。

3、如果某仓库更换了管理员,会带来什么问题?——这个仓库有几条物品存放记录,就要修改多少次管理员信息。

所以,在某些特殊情况下,即使关系模式符合 3NF 的要求,仍然存在着插入异常,修改异常与删除异常的问题。需要再次改进设计。

造成此问题的原因:存在着主属性对于码的部分函数依赖传递函数依赖。主属性仓库名对于码(管理员,物品名)的部分函数依赖。

解决办法就是要在 3NF 的基础上消除主属性对于码的部分与传递函数依赖即可。

仓库(仓库名,管理员)

库存(仓库名,物品名,数量)

这样,之前的插入异常,修改异常与删除异常的问题就被解决了。

posted @ 2018-11-15 12:55  丶中医  阅读(238)  评论(0编辑  收藏  举报