数据库的范式和反范式设计

范式与反范式



1.1  范式

设计关系型数据库时,需要遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式Normal Form,越高的范式数据库冗余越小。应用数据库范式可以带来许多好处,但是最主要的目的是为了消除重复数据,减少数据冗余,让数据库内的数据更好的组织,让磁盘空间得到更有效的利用。范式的缺点:范式使查询变的相当复杂,在查询时需要更多的连接,一些复合索引的列由于范式化的需要被分割到不同的表中,导致索引策略不佳。

1.1.1  什么是第一、二、三BC范式/span>

所谓“第几范式”,是表示关系的某一种级别,所以经常称某一关系R为第几范式。目前关系型数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。满足高等级的范式的先决条件是必须先满足低等级范式。

在关系数据库中,关系是通过表来表示的。在一个表中,每一行代表一个联系,而一个关系就是由许多的联系组成的集合。所以,在关系模型中,关系用来指代表,而元组用来指代行,属性就是表中的列。对于每一个属性,都存在一个允许取值的集合,称为该属性的域。

下面介绍范式中会用到的一些常用概念。

① 实体(Entity):就是实际应用中要用数据描述的事物,它是现实世界中客观存在并可以被区别的事物,一般是名词。比如“一个学生”、“一本书”、“一门课”等等。值得强调的是,这里所说的“事物”不仅仅是看得见摸得着的“东西”,它也可以是虚拟的,比如说“老师与学校的关系”。

② 数据项(Data Item):即字段(Fields)也可称为域、属性、列。数据项是数据的不可分割的最小单位。数据项可以是字母、数字或两者的组合。通过数据类型(逻辑的、数值的、字符的等)及数据长度来描述。数据项用来描述实体的某种属性。数据项包含数据项的名称、编号、别名、简述、数据项的长度、类型、数据项的取值范围等内容。教科书上解释为:“实体所具有的某一特性”,由此可见,属性一开始是个逻辑概念,比如说,“性别”是“人”的一个属性。在关系数据库中,属性又是个物理概念,属性可以看作是“表的一列”。

③ 数据元素(Data Element):数据元素是数据的基本单位。数据元素也称元素、行、元祖、记录(Record)。一个数据元素可以由若干个数据项组成。表中的一行就是一个元组。

④ 码:也称为键(Key),它是数据库系统中的基本概念。所谓码就是能唯一标识实体的属性,它是整个实体集的性质,而不是单个实体的性质。它包括超码、候选码和主码。

⑤ 超码:超码是一个或多个属性的集合,这些属性的组合可以在一个实体集中唯一地标识一个实体。如果K是一个超码,那么K的任意超集也是超码,也就是说如果K是超码,那么所有包含K的集合也是超码。

⑥ 候选码:在一个超码中,可能包含了无关紧要的属性,如果对于一些超码,他们的任意真子集都不能成为超码,那么这样的最小超码称为候选码。

⑦ 主码:从候选码中挑一个最少键的组合,它就叫主码(主键,Primary Key)。每个主码应该具有下列特征:1.唯一的。2.最小的(尽量选择最少键的组合)。3.非空。4.不可更新的(不能随时更改)。

⑧ 全码:如果一个码包含了所有的属性,这个码就是全码(All-key)。

⑨ 主属性:一个属性只要在任何一个候选码中出现过,这个属性就是主属性(Prime Attribute)。

⑩ 非主属性:与主属性相反,没有在任何候选码中出现过,这个属性就是非主属性(Nonprime Attribute)或非码属性(Non-key Attribute)。

外码:关系模式R中的一个属性或属性组X并非R的码,但X是另一个关系模式的码,则称XR的外码,也称外键(Foreign Key)。例如,在SC(Sno,Cno,Grade)中,Sno不是码,但Sno是关系模式S(Sno,Sdept,Sage)的码,则Sno是关系模式SC的外码。主码与外码一起提供了表示关系间联系的手段。

依赖表(Dependent Table):也称为弱实体(Weak Entity)是需要用父表标识的子表。

关联表(Associative Table):是多对多关系中两个父表的子表。

函数依赖:函数依赖是指关系中一个或一组属性的值可以决定其它属性的值。函数依赖就像一个函数y=f(x)一样,x的值给定后,y的值也就唯一地确定了,写作X Y函数依赖不是指关系模式R的某个或某些关系满足的约束条件,而是指R的一切关系均要满足的约束条件。

完全函数依赖:在一个关系中,若某个非主属性数据项依赖于全部关键字称之为完全函数依赖。例如,在成绩表(学号,课程号,成绩)关系中,(学号,课程号)可以决定成绩,但是学号不能决定成绩,课程号也不能决定成绩,所以“(学号,课程号)→ 成绩”就是完全函数依赖。

传递函数依赖:指的是如果存在A B C”的决定关系,则C传递函数依赖于A

下表列出了各种范式:


D:.Users.XIAOMA~1.AppData.Local.Temp.ksohtml.wps7ACF.tmp.jpg 

学习了范式,为了巩固理解,接下来设计一个论坛的数据库,该数据库中需要存放如下信息:

1)用户:用户名,EMAIL,主页,电话,联系地址

2)帖子:发帖标题,发帖内容,回复标题,回复内容

第一次可以将数据库设计为仅仅存在一张表:

用户名 EMAIL 主页 电话 联系地址 发帖标题 发帖内容 回复标题 回复内容

这个数据库表符合第一范式,但是没有任何一组候选关键字能决定数据库表的整行,唯一的关键字段用户名也不能完全决定整个元组。所以,需要增加“发帖ID”、“回复ID”字段,即将表修改为:

用户名 EMAIL 主页 电话 联系地址 发帖ID 发帖标题 发帖内容 回复ID 回复标题 回复内容

这样数据表中的关键字(用户名,发帖ID,回复ID)能决定整行:

(用户名,发帖ID,回复ID)→(EMAIL,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容)

但是,这样的设计不符合第二范式,因为存在如下决定关系:

(用户名)→(EMAIL,主页,电话,联系地址)

发帖ID→(发帖标题发帖内容

回复ID)→(回复标题回复内容

即非关键字段部分函数依赖于候选关键字段,很明显,这个设计会导致大量的数据冗余和操作异常。

因此,需要对这张表进行分解,具体可以分解为(带下划线的为关键字):

1)用户信息:用户名EMAIL,主页,电话,联系地址

2)帖子信息:发帖ID,标题,内容

3)回复信息:回复ID,标题,内容

4)发贴:用户名,发帖ID

5)回复:发帖ID,回复ID

这样的设计是满足第123范式和BCNF范式要求的,但是这样的设计是不是最好的呢一定。

观察可知,第4项“发帖”中的“用户名”和“发帖ID”之间是1N的关系,因此,可以把“发帖”合并到第2项的“帖子信息”中;第5项“回复”中的“发帖ID”和“回复ID”之间也是1N的关系,因此,可以把“回复”合并到第3项的“回复信息”中。这样可以一定程度地减少数据冗余,新的设计如下所示:

1)用户信息:用户名,EMAIL,主页,电话,联系地址

2)帖子信息:用户名,发帖ID,标题,内容

3)回复信息:发帖ID,回复ID,标题,内容

数据库表1

来源:小麦苗DBA宝典

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2017年6月16日
下一篇 2017年6月16日

相关推荐