数据库原理及MySQL应用 | 关系规范化

举报
TiAmoZhang 发表于 2022/12/29 13:19:25 2022/12/29
【摘要】 关系数据库的数据模式设计不当,就会出现数据冗余,从而导致操作异常。对关系模式进行范式优化,使得数据的冗余度最小化以及运行效率最大化。

各位看官,各位朋友,久等了,终于有时间更新了 !

关系数据库的数据模式设计不当,就会出现数据冗余,从而导致操作异常。对关系模式进行范式优化,使得数据的冗余度最小化以及运行效率最大化。

01、第一范式


第一范式(First Normal Form)简称1NF,是对关系模式的最基本要求。也就是说,一个二维表格,只有满足1NF的要求,才能被称为关系。

如果关系模式R的每个属性都是原子的,即每个属性对应的域中的每个元素都是不可再分的最小单元,则称R属于第一范式,记作R∈1NF。

如表1所示的二维表格中,由于每位顾客作为一行,每位顾客可以生成多张订单,而每张订单中也可以包含多本图书,所以在orderid、orderdate、bookid、title、quantity、ctgcode、ctgname列中,针对每个行都可能出现多个值,也就是说这些列中存放的值不具有原子性,存在“表中表”的结构,所以这个二维表格不满足第一范式的要求,不能存放在关系数据库中。

■ 表1 图书销售表booksale

对该二维表格进行规范化处理,可以得到表2所示的满足第一范式的关系。

■ 表2满足第一范式的图书销售关系booksale 

通过对表2所示的关系分析可知,数据之间存在如下联系:

(1) 每位顾客可以拥有多张订单,每张订单只属于一位顾客。

(2) 每张订单里可以包含多册图书,每册图书也可以被包含在多张订单里。

(3) 每册图书属于一个类别,每个类别下可以有多册图书。

在这个关系中,任意一个orderid和bookid属性的值的组合都可以唯一地确定一条图书销售记录,所以(orderid, bookid)是这个关系的候选键。(orderid, bookid)是这个关系唯一的候选键,可以将其视为该关系的主键,这个关系的关系模式可以描述为:

Booksale (cstid, cstname, orderid, orderdate, bookid, title, quantity, ctgcode, ctgname)


02、操作异常问题


虽然关系模式Booksale满足第一范式,但是该关系模式下的具体关系中可能存在着大量的数据冗余。数据冗余不仅会占用更多的存储空间,而且在对关系进行插入、更新、删除操作的过程中还可能发生操作异常,引发数据不一致的问题。

1. 插入异常


如果有一位顾客想要注册为会员,但是他还从未购书,因为该记录缺少主键,所以这位顾客的信息无法插入到该关系中。也就是说,需要插入到关系中的记录无法插入到关系中。

如果将booksale关系中的数据分别存储在如表2-22~表2-27所示的5个关系中,那么就可以将这位会员的信息直接插入到关系customers中,解决想要插入记录而无法插入的问题。

 对应的关系模式为:

  • Customers (cstid, cstname)
    Orders (orderid, orderdate, cstid[FK])
    Books (bookid, title, ctgcode[FK])
    Categories (ctgcode, ctgname)
    Orderitems (orderid[FK], bookid[FK], quantity)


2. 删除异常


在图书销售booksale关系中,如果将订单号orderid为4的订单信息删除,那么顾客“李明宇”的信息也会被同时删除,或者说“李明宇”的信息就无法保存在这个关系中了。也就是说,不希望删除的数据被删除了。

如果将关系分解为5个“小”关系,则删除orderid为4的订单记录只需要在orders关系中删除对应的元组即可,不会影响到顾客信息的存储,也就避免了删除异常的问题。

3. 更新复杂


当需要更新关系中的数据时,例如更新书号bookid为10号的图书的书名title的时候,因为该图书的信息重复存储,所以需要将所有图书的书名title同时正确更新,否则就会出现数据不一致的问题。

如果将关系分解为5个“小”关系,则更新10号图书的书名的操作仅需在books关系中更新一个元组,不会造成更新后数据不一致的情况发生。

关系模式booksale以及由该关系模式分解得到的5个关系模式,都是满足1NF的关系,都可以用来在数据库中存放相关数据,但是它们有各自的优缺点。

将关系booksale分解为5个关系后,可以避免数据冗余以及操作异常问题,但是会增加数据查询的复杂程度。例如:想要查看顾客“张志远”订购的图书的书号、书名、类别名称,如果通过booksale关系查询,则关系代数表达式非常简单: 
同样的查询操作,如果通过分解后的5个关系进行查询,则需要先将关系连接起来再进行查询。

由于连接运算在数据库操作中既消耗系统资源又效率非常低,所以如果将关系模式分解得过于“小”,会影响数据库的查询操作性能。

03、函数依赖


函数依赖是最重要的一种数据依赖,在对关系模式进行规范化处理的过程中,主要使用函数依赖来分析关系中存在的数据依赖特点。

1. 函数依赖的概念


假设X和Y是关系模式R中的两个不同的属性或属性组,如果对于X中的每一个具体值,Y中都有唯一的具体值与之对应,则称Y函数依赖于X,或X函数决定Y,记作X→Y,其中X被称为决定因素。

当X→Y,并且Y包含于X时,称X→Y是平凡函数依赖;当X→Y,并且Y不包含于X时,称X→Y是非平凡函数依赖。这里讨论的是非平凡函数依赖。

以Booksale关系模式为例,因为对于属性cstid中的每一个具体值,在属性cstname中都只有唯一一个值与之对应,所以cstid函数决定cstname,即cstid→cstname。但反过来,因为可能存在顾客重名的情况,对于属性cstname中的一个值,可能对应属性cstid中的多个值,所以cstname不能函数决定cstid,记作

由于一张订单里的一册图书的销售数量是一定的,所以orderid和bookid组合起来可以决定quantity,即(orderid,bookid)→quantity。

2. 部分函数依赖与完全函数依赖


假设X→Y是关系模式R中的一个函数依赖,如果存在X的真子集X′,使得X′→Y成立,则称Y部分依赖于X,记作

;如果在X中找不到一个真子集X′,使得X′→Y成立,则称Y完全依赖于X。

在关系模式Booksale中

就是一个部分函数依赖。因为决定因素(orderid, bookid)的一个真子集bookid就可以函数决定price,即bookid→price。

(orderid,bookid)→quantity是一个完全函数依赖,因为决定因素的任何一个真子集都不能函数决定quantity。

3. 传递函数依赖


在关系模式R中,如果存在函数依赖X→Y,Y→Z,而

,则称Z传递依赖于X,记作。

在关系模式Booksale中,bookid→ctgcode,ctgcode→ctgname,而

,所以是一个传递函数依赖。

提示/

因为部分函数依赖一定是传递函数依赖,所以如果关系模式中不存在传递函数依赖,则一定不存在部分函数依赖。

04、第二范式


包含在主键中的属性称为主属性;不包含在主键中的属性称为非主属性。

如果关系模式R属于1NF,并且每个非主属性都完全函数依赖于R的主键,那么称R属于第二范式,记作R∈2NF。

在关系模式Booksale中,除了属性quantity对主键(orderid, bookid)的函数依赖是完全函数依赖以外,其他非主属性对主键的函数依赖都是部分函数依赖,因为主键的真子集orderid可以函数决定属性orderdate、cstid和cstname;主键的另外一个真子集bookid可以函数决定属性title、ctgcode和ctgname。即:

由于该关系模式中存在着非主属性对主键的部分函数依赖,所以这个关系模式不属于第二范式。

为了将关系模式规范到2NF,可以对关系模式做如下处理:

(1) 将那些部分依赖于主键的属性从关系模式中取出,再复制它们所依赖的主属性作为新关系模式的主键来构成一个新的关系模式。

(2) 剩下的属性构成另一个关系模式。

例如,将属性orderdate、cstid和cstname从原关系模式中取出,再复制它们所依赖的主属性orderid作为新关系模式的主键,构成新关系模式Orders(orderid, orderdate, cstid, cstname);将属性title、ctgcode和ctgname从原关系模式中取出,再复制它们所依赖的主属性bookid作为新关系模式的主键,构成新关系模式Books(bookid, title, ctgcode, ctgname);原关系模式中剩余的属性构成一个新的关系模式OrderItems(orderid[FK], bookid[FK], quantity)。

所以关系模式Booksale可以规范为以下三个关系模式。这三个关系模式不存在非主属性对主键的部分函数依赖,所以它们都是2NF的关系模式。分解得到的这三个新的关系模式可以通过外键连接起来。

分解后的关系模式仍然存在数据冗余,例如在关系模式Orders中,一位顾客可以有多张订单,所以顾客的信息会重复存储;在关系模式Books中,一个类别下可以有多册图书,那么图书类别信息会重复存储。

05、第三范式


如果关系模式R属于1NF,并且每个非主属性都不传递函数依赖于R的主键,那么称R属于第三范式,记作R∈3NF。

在关系模式Orders中,主键orderid函数决定cstid,cstid函数决定cstname,而cstid不能函数决定orderid,所以cstname对主键orderid的函数依赖是传递函数依赖,即:

由于关系模式Orders中存在着非主属性对主键的传递函数依赖,所以这个关系模式不满足3NF。

为了将关系模式规范到3NF,可以对关系模式做如下处理:

(1) 将那些传递函数依赖于主键的属性从关系模式中取出,再复制它们所直接函数依赖的属性作为新关系模式的主键来构成一个新的关系模式。

(2) 剩下的属性构成另一个新关系模式。

例如,将属性cstname从原关系模式中取出,再复制它所直接函数依赖的属性cstid作为新关系模式的主键,构成新关系模式Customers(cstid, cstname);原关系模式中剩余的属性构成一个新的关系模式Orders(orderid, orderdate, cstid[FK])。

分析关系模式Books,包含如下函数依赖:
关系模式Books同样存在非主属性对主键的传递函数依赖,所以该关系模式不满足3NF。

通过同样的方法分解关系模式Books得到两个新关系模式。最终,总共得到5个新关系模式,如下所示。具体关系以及关系中的数据如表2-22~表2-26所示。

这5个分解得到的关系模式都不存在非主属性对主键的传递函数依赖,所以它们都是3NF的关系模式。分解得到的这5个新的关系模式可以通过外键连接起来。

最早被提出的关系范式是第一范式(1NF)、第二范式(2NF)和第三范式(3NF),接着由R. Boyce和E. F. Codd于1974年共同提出了Boyce-Codd范式(BCNF),这个关系范式是对3NF的增强定义。以上4个关系范式中除了1NF以外的3个关系范式都是基于属性之间的函数依赖提出的。比BCNF级别更高的关系范式还包括1977年提出的第四范式(4NF)和1979年提出的第五范式(5NF),其中4NF建立在多值依赖的基础上,5NF建立在连接依赖的基础上。图2-6是各个关系范式之间的关系。

■ 图2-6关系范式之间的关系

在对关系模式进行设计的时候,并不是规范化程度越高的关系模式就越好。如果对数据库的操作主要是查询,而更新较少时,为了提高效率,宁可保留适当的数据冗余而不要将关系模式分解得太小,否则为了查询数据,常常要做大量的连接运算,反而会花费大量的时间,降低查询的效率;当对数据库中的数据操作主要是插入、更新和删除操作时,为了避免数据操作异常的发生,应该尽量将关系模式规范到3NF。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。