「软件架构师」-数据库系统之数据的规范化和反规范化

「软件架构师」-数据库系统之数据的规范化和反规范化

数据的规范化

范式:关系模型满足的确定约束条件,根据满足约束条件的级别不同,范式由低到高分为1NF(第一范式)、2NF(第二范式)、3NF(第三范式)、BCNF(BC范式)、4NF(第四范式)等。不同的级别范式性质也不同。

把一个低一级的关系模型分解为高一级关系模型的过程,称为关系模型的规范化。关系模型分解必须遵守两个准则:

  1. 无损连接性:信息不失真(不增减信息);
  2. 函数依赖保持性:不破坏属性间存在的依赖性。

规范化的基本思想是逐步消除不合适的函数依赖,使数据库中的各个关系模型达到某种程度的分离。规范化解决的主要是单个实体的质量问题,是对于问题域中原始数据展现的正规化处理。规范化理论给出了判断关系模型优劣的理论标准,帮助预测模式可能出现的问题,是数据库设计的指南和工具,具体有:

  1. 用数据依赖的概念分析和表示数据项之间的关系;
  2. 消除E-R图中的冗余关系。

函数依赖:通俗的说,就像自变量x确定之后,相应的函数值f(x)也就唯一确定了一样,函数依赖是衡量和调整数据规范化的最基础的理论依据。例如,记录职工信息的结构如下:

职工工号(EMP_NO)、职工姓名(EMP_NAME)、所在部门(DEPT)。

则说EMP_NO函数决定了EMP_NAME和DEPT,或者说EMP_NAME/DEPT依赖于EMP_NO,记为EMP_NO→EMP_NAME、EMP_NO→DEPT。

第一范式

1NF是最低的规范化要求。如果关系R中所有的属性的值域都是简单域,其元素(即属性)不可再分,是属性项而不是属性组,那么关系模型R是第一范式的,记作RÎ1NF。这一限制是关系的基本性质,所以任何关系都必须满足第一范式。第一范式是实际数据库设计中必须先达到的,通常称为数据元素的结构化。如下图1,不满足1NF的例子和图2满足1NF的例子:

「软件架构师」-数据库系统之数据的规范化和反规范化

图1,不满足1NF

「软件架构师」-数据库系统之数据的规范化和反规范化

图2,满足1NF

经过处理后,就可以以省、市为条件进行查询和统计了。满足1NF的关系模型会出现很多重复值,并且增加了修改其数据时引起疏漏的可能性。为了消除这种数据冗余和避免更新数据的遗漏,需要增加更加规范的2NF。

第二范式

2NF:如果一个关系R属于1NF,且所有的非主属性都完全依赖于主属性,则称为第二范式,记作RÎ2NF。

为了说明问题,用一个例子说明:有一个获得专业技术证书的人员情况登记表结构如下:

省份、姓名、证书名称、证书编号、核准项目、发证部门、发证日期、有效期。

这个结构符合1NF,其中“证书名称”和“证书编号”是主码,但是“发证部门”只完全依赖于“证书名称”,即只依赖于主关键字的一部分(即部分依赖),所以它不符合2NF,这样首先存在数据冗余,因为证书的种类可能不多。其次,在更改发证部门的时候,如果漏改了某一记录,存在数据不一致。再次,如果获得某种证书的职工全部跳槽了,那这个发证部门的信息就可能丢失了,即这种关系不允许存在某种证书没有获得者的情况。

可以用分解的方法消除部分依赖的情况,而使关系达到2NF的标准。方法是:从现有关系中分解出新的关系表,使得每个表中所有的非关键字都完全依赖于各自的主关键字。可以分解成两个表(省份、姓名、证书名称、证书编号、核准项目、发证日期、有效期)和(证书名称、发证部门),这样就完全符合2NF了。

第三范式

3NF:如果一个关系属于2NF,且每个非主属性不传递依赖于主属性,这种关系称为3NF,记作RÎ3NF。

从2NF中消除传递依赖,就是3NF。例如:有一个表(职工姓名,工资级别,工资额),其中职工姓名是关键字,此关系符合2NF,但是因为工资级别决定工资额,也就是说非主属性“工资额”传递依赖于主属性“职工姓名”,它不符合3NF,同样可以使用投影分解的方法分解成两个表:(职工姓名,工资级别)和(工资级别,工资额)。

BC范式

一般满足3NF的关系模型已经消除冗余和各种异常现象,获得比较满意的效果。但无论是2NF还是3NF都没有涉及主属性间的函数依赖,所以还是会有时引起一些问题。由此引入BC范式(由Boyeet和Codd提出)。通常认为BCNF是3NF的改进。

BC范式的定义:如果关系模型R∈1NF,且R中每一个函数依赖关系中的决定因素都包含码,则R是满足BC范式的关系,记作RÎBCNF。当一个关系模型RÎBCNF,则在函数依赖范畴里,就认为已经彻底实现了分离,消除了插入、删除的异常。

综合1NF、2NF和3NF、BCNF的内涵可概括如下:

  1. 非主属性完全函数依赖于码(2NF的要求);
  2. 非主属性不传递依赖于任何一个候选码(3NF的要求);
  3. 主属性对不包含它的码完全函数依赖(BCNF的要求);
  4. 没有属性完全函数依赖于一组非属性(BCNF的要求)。

反规范化

数据库中的规范化的优点是减少了数据冗余,节约了存储空间,相应的逻辑和物理的I/O次数减少,同时加快了增加、删除、修改的速度,但是对完全规范的数据库进行查询的时候,通常需要更多的连接操作,从而影响查询的效率。因此,有时为了提高某些查询或应用的性能而破坏规范化规则,即反规范化(非规范化处理)。

常见的范规范化技术有:

1、增加冗余列

增加冗余列是指在多个表中具有相同的列,它常用来在查询时避免连接操作。例如:以规范化设计理念,学生成绩表中不需要“姓名”,因为“姓名”字段可通过学号查询到,但在反规范化设计中,会将“姓名”字段加入表中。这样查询一个学生的成绩时,不需要与学生表进行连接操作,便可以得到对应的“姓名”。

2、增加派生列

增加派生列是指增加的列可以通过表中的其他数据计算生成。它的作用是在查询时减少计算量,从而加快查询速度。例如:订单表中,有商品号,商品单价,采购数量,我们需要订单总价时,可以通过计算得到总价,所以规范化设计理念是不用在订单表中设计“订单总价”字段的。但范规范化就不这样考虑,由于订单总价在每次查询都需要计算,这样会占用系统大量资源,所以在此表中增加了派生列“订单总价”以提高查询效率。

3、重新组表

有时候对表进行分割可以提高性能。表分割分为两种方式:

水平分割:根据一列或多列数据的值把数据行放到两个独立的表中。水平分割通常在下面的情况下使用:

  • 情况1:表很大,分割后可以降低在查询时需要读取的数据和索引的页数,同时也降低了索引的层数,提高查询效率。
  • 情况2:表中的数据本来就有独立性。例如表中分别记录各个地区的数据或不同时期的数据,特别是有些数据常用,而另外一些数据不常用。
  • 情况3:需要把数据放到多个介质上使用时。

垂直分割:把主码和一些列放到一个表,然后把主码和另外一些列放到另一个表中。如果一些表中的某些列常用,而另外一些列不常用,则可以采用垂直分割,另外垂直分割可以使得数据行变小,一个数据页就能存储更多的数据,在查询时会减少I/O次数。其缺点是需要管理冗余列,查询所有数据需要连接操作。

「软件架构师」-数据库系统之数据的规范化和反规范化


分享到:


相關文章: