数据库设计中反规范化技术的应用

来源:互联网 发布:windows兼容性 编辑:程序博客网 时间:2024/05/22 07:56

 【摘 要】数据库的规范化理论不仅仅是关系模式设计的理论指导和强有力的工具,对其它数据模型数据库的逻辑设计也
同样有理论意义,数据的规范化不仅会带来空间上的效率,而且还有助于保证数据的正确性和一致性。它是现在数据库原理教
学中一个重要的环节,但是,在实际应用中,数据库的规范化也会带来其它的影响,它使数据的查询越来越复杂,数据的查询
性能降低,所以在实际应用时常常对数据库进行反规范化。文章陈述了在数据库建模过程中进行反规范化的基本原则和方法。

 

数据库设计包括数据库的逻辑设计和物理设计,在数据
库的逻辑设计中,数据的规范化不仅会带来空间上的效率,
而且还有助于保证数据的正确性和一致性,在现在的各类教
材中,主要是讲解数据库的规范化问题,但数据库的规范化
使得查询越来越复杂,对数据的查询性能有较大的影响,如
何设计一个合理的数据,其设计的原则是什么,必须根据实
际应用进行具体的系统分析,权衡各方面的因素后,选择最
优设计方案。
(一)数据库的规范化设计
规范化理论是研究如何将一个不好的关系模式转化为好
的关系模式的理论,关系数据库中的关系要满足一定的要求
即规范(约束条件),满足不同程度要求的为不同范式,规范
化理论把关系应满足的规范要求分为几级,分别是:第一范
式(1NF),第二范式(2NF),第三范式(3NF),BCNF 范式,4NF,
5NF。范式的等级越高,应满足的约束集条件也越严格,规范
的每一级别都依赖于它的前一级别。
数据库中的数据规范化的优点是减少了数据冗余,节约
了存储空间,相应逻辑和物理的I/O 次数减少,同时加快了
增、删、改的速度,从关系模型的角度来看,数据表最好满
足3NF 最符合标准,这样的设计容易维护。
(二)数据库的反规范
未经规范化的数据库一般都有下述缺点:较大的数据冗
余,数据一致性差,数据修改复杂,对表进行插入删除时会
产生异常。规范化的作用就在于尽量去除冗余,使数据保持
一致,使数据修改简单,除去在表中进行插入删除时产生的
异常现象,有时故意保留成非规范化的数据结构,或者规范
化以后又反规范了,这样做通常是为了改进性能。
1.反规范化的必要性
数据库的规范化提高了系统性能,但不是单纯为了规范
化而规范化,一个完全规范化的设计并不总能生成最优的性
能,特别高范式等级的数据库在网络中不一定有高性能,因
为使数据库规范化的方法是把表拆分成相关列最少的表,在
进行数据库查询时,通常需要更多的复杂的联结操作,这样
查询时就需要用占用较多的CPU 资源和输入输出操作,才能
查到客户端所需的数据,这会导致复杂度的增加和性能的下
降,从而影响查询的速度,因此,有时为了提高某些查询或
应用的性能而破坏规范规则,特别在网络环境中,有必要对
规范化进行必要的平衡,使系统有最优的性能,提高数据库
的网络性能,即反规范。例如:学生收费系统中,有两个表:
收费标准={学号,收费标准,已收费,收费项目,收费年
度}
收费收据={收据序列号,学号,收费日期,摘要信息,
收款人}
收据明细={收据序列号,收费项目,缴费金额,费用年
度}
从理论上讲,我们可以根据收费收据,无需收费标准中
的“已收费”列,统计学生某年度nd 的已缴费用通过如下的
SQL 语句即可得到,即:
SELECT 学号,sum(缴费金额)
FROM 收费收据, 收据明细
WHERE 收费收据.收据序列号=收费收据.收据序列号
AND 费用年度=@nd
GROUP BY 学号
但是,由于学生并非一次性缴清,可能分多次缴款,所
以要查询指定学生的欠款情况就复杂,利用这样的数据库模
式实现比较困难。若在表“收费标准”中增加”已收费”列,
每次收款时对指定学生指定项目指定年度的“已收款”进行
累加,这样就十分方便的统计学生的应缴款、已缴款、欠款。
用如下的SQL 语句即可轻松的完成
Select 学号,收费标准, 已收费,Sum(收费标准-已
收费)
From 收费标准
Group BY 学号
另一种情况,在收据表“收费收据”、“收据明细”中,
没有学生“姓名”列,只有“学号”列,要查询交费情况学
生的姓名,必须与“学生表”连接才能完成。一种特殊情况,
如果学生在缴款后,学生改名,此时查询输出的收据信息就
和原始的收据信息有差异,这种情况在实际应用中是不允许
的。所以,在“收费收据”表中增加一列“姓名”,这样,保
证了收据的原始信息的正确性。

2.有选择地实现模型的反规范化技术
进行反规范操作,要充分考虑数据的存取需求、表的大
小、一些特殊的计算(例如合计)、数据的物理存储位置、应
用需求特征等。常用的反规范技术是有意识的增加数据的冗
余度,特别在网络数据库中适当增加数据的冗余是有好处的。
增加冗余分两个层次:一是数据库层,二是表层。
数据库层数据冗余:系统建模无论采用何种体系结构,
冗余数据可以数据副本的方式出现,副本的存在使许多应用
可以“本地性”,大大减少了网络通信,提高了系统的性能。
再有当某一结点出现故障时,由于拷贝副本的存在,系统仍
可对此副本操作,而不至于因一处故障而使系统无法使用。
表层数据冗余:一是建立临时表或定义视图以减少频繁
出现的多表联结,二是在数据库的设计时仅采用恰当的范式
等级,增加冗余列。
(1)增加冗余列
是指在多个表中具有相同的列,它常用来在查询时避免
连接操作。例如在“教务管理系统中”中,按照规范化的要
求,一般有建立如下表
课程={课程号,课程名称}
教师={教师编号,教师姓名,}
教学={课程编号,教师编号,课时}
在实际应用中,经常检索一门课为“数据库原理”的任
课教师姓名、课时等信息,则需要将“课程”表、“教师”和
“任课”表的连接查询:采用如下的SQL 语句:
Select 教师.教师姓名, 教学.课时
from 课程, 教师,教学
where 教学. 教师编号=教师. 教师编号 and
教学. 课程编号=课程. 课程号and
课程. 课程名称=“C1”
如果在“教学”表中增加一列“教师姓名”就可以减少
连接操作了。增加冗余列可以在查询时避免连接操作,但它
需要更多的磁盘空间,同时增加了对表维护的工作量。确定
是否增加列要视系统的具体情况,要根据查询的频度、表维
护的工作量、数据量的大小来确定。
(2)增加派生列
指增加的列来自其它表中的数据,由它们计算生成。它
的作用是在查询时减少连接操作,避免使用集函数。
例如在“销售管理系统”中,有三个表:
销售定单={定单编号,定单日期}
定单明细={定单编号,产品编号,数量}
价格表={产品编号,价格开始执行时间,价格结束执行时
间,单价}
为了要求计算出一个定单的全部金额,需要做以下的工
作:
● 找出定单中的所有产品项,每一项对应为产品编号以
及该的订购数量。
● 对每一个订购产品,使用订购单中的订购日期来找到
该产品在下订购单时的价格。
● 合计所有计算出的价格。
用户每次查看其定单信息时,都需要涉及这三个表,对
该数据模型做如下的修改。增加一派生列“定单金额“。
销售定单={定单编号, 定单日期,定单金额}
采用此方法后,查询一个定单的金额就容易得多,但对
“定单”的修改都必须对”定单金额”进行更新,它只适合
与不经常对“定单”进行修改的情况下。派生列也具有与冗
余列、数据一致性等缺点,在实际应用中,对于具有比较复
杂的运算的时候可以采用此方法。
(3)复制副本
在分布式网络数据库中,可以在本地建立相关数据库副本,
对于一些常用的数据检索,直接从本地数据库获取。例如“学
生成绩登陆与查询系统”中,在教师进行成绩进行登记时,
可以先将学生的相关信息在本地建立副本,当教师确认成绩
完成登记时,再将数据传输到网络数据库,若传输中有误,
可以重新连接网络传输。这样,可以保证数据传输的正确性,
以及数据检索的速度。现在许多的“证券分析系统”都采用
此方法,将股票相关信息在连接网络时在本地建立副本,以
提高数据检索和统计分析的速度。
(4)将过程数据的计算保存在一个本地表中
对于有些查询,可能要经过大量的对不同表格的运算,
才能得到结果,这种查询的实际运用中要多次出现,我们可
以建立一个副本,将运算的结果存入到副本中,查询时只在
副本中查询即可。如在“收费系统中”,要查询“某班各年度
的应交款、已交款、欠款情况”,需要做以下的工作:
● 确定学生所在的班级
● 学生交款情况
● 按年度分班统计
如果设置一临时表专门来存放该信息、则完成此查询就
方便多了。
班级交款表={班级,年度,收费标准,已缴款}
(5)增加标识列
当一个表需要多个列的组合才能组成主键时,可以在表
中合理的增加一列作为主键,唯一标识此表中的记录,一般
这一列用的值是一个编号或是时间戳(timestamp)。在这种情
况下增加列虽然多占了存贮空间,但是在索引中以此列代替
大的组合键,从而获得了性能的提高。另外,为了应用程序
设计的方便,也常在表中增加标识列,如“在学生收费系统”
中,对于“收据表”
收费收据={收据序列号, 学号, 收费日期, 摘要信息,
收款人}
可以增加标识列“状态”,根据不同数据处理的不同业务
流程,确定“状态”的值,如状态可以设为“未结帐、结帐、
作废”等。这样就方便的表达了收据的状况,对数据的统计
分析,也很方便。
(三)结束语
规范化后的表一般都较小,小的表意味着一个数据页中
可以包含较多的记录,这样客户端用户就可在同样的时间内
获得所需的更多数据记录,从而减少客户端与服务器端的物
理输入与输出,减轻网络的负担。数据库的反规范设计可以
提高查询性能,降低连接操作的需求,降低外码和索引的数目,
还可能减少表的数目。但相应带来的问题是可能出现数据的
完整性问题。因此在做反规范时,一定要权衡利弊,仔细分
析应用的数据存取需求和实际的性能特点。
原创粉丝点击