关系数据理论中的范式

标准化表示从你的数据存储中移去数据冗余(redundancy)的过程。如果数据库设计达到了完全的标准化,则把所有的表通过关键字连接在一起时,不会出现任何数据的复本(repetition)。标准化的优点是明显的,它避免了数据冗余,自然就节省了空间,也对数据的一致性(consistency) 提供了根本的保障,杜绝了数据不一致的现象,同时也提高了效率。

第一范式(1NF; The First Normal Form)

第一范式是最低的规范化要求,第一范式要求数据表不能存在重复的记录,即存在一个关键字。1NF的第二个要求是每个字段都不可再分,即已经分到最小,关系数据库的定义就决定了数据库满足这一条。主关键字达到下面几个条件:
1. 主关键字段在表中是唯一的;
2. 主关键字段中没有复本;
3. 主关键字段不能存在空值;
4. 每条记录都必须有一个主关键字;
5. 主关键字是关键字的最小子集;

满足1NF的关系模式有许多不必要的重复值,并且增加了修改其数据时疏漏的可能性。为了避免这种数据冗余和更新数据的遗漏,就引出了第二范式(2NF)。

第二范式(2NF; The Second Normal Form)

定义:如果一个关系属于1NF,且所有的非主关键字段都完全地依赖于主关键字,则称之为第二范式,简记为2NF
为了说明问题现举一个例子来说明:

有一个库房存储的库有四个字段(零件号码,仓库号码,零件数量,仓库地址),这个库符合1NF,其中“零件号码”和“仓库号码”构成主关键字。
但是因为“仓库地址”只完全依赖与“仓库号码”,即只依赖于主关键字的一部分,所以它不符合2NF,这样首先存在数据冗余,因为仓库数量可能不多。
其次,存在如果更改仓库地址时,如果漏改了某一记录,存在数据不一致性。
再次,如果某个仓库的零件出完了,那么这个仓库地址就丢失了,即这种关系不允许存在某个仓库中不放零件的情况。
我们可以用投影分解的方法消除部分依赖的情况,而使关系达到2NF的标准。
方法是从关系中分解出新的二维表,是每个二维表中所有的非关键字都完全依赖于各自的主关键字。我们可以如下分解:分解成两个表(零件号码,仓库号码,零件数量)和(仓库号码,仓库地址)。这样就完全符合2NF了。

第三范式(3NF; The Third Normal Form)

定义:如果一个关系属于2NF,且每个非关键字不传递依赖于主关键字,这种关系是3NF
从2NF中消除传递依赖,就是3NF。

比如有一个表(姓名,工资等级,工资额),其中姓名是关键字,此关系符合2NF,但是因为工资等级决定工资额,这就叫传递依赖,它不符合3NF,我们同样可以使用投影分解的办法分解成两个表:(姓名,工资等级),(工资等级,工资额)。

一般情况,规范化到3NF就满足需要了,规范化程度更高的还有BCNF,4NF,5NF,因为不常用,不作解释和讨论。它们下层都是上层的子集,规范办法是:

1NF(消除非主属性对关键字的部分函数依赖)=> 

2NF(消除非主属性对关键字的传递函数依赖)=>

3NF (消除主属性对关键字的部分和传递依赖)=>

BCNF (消除非平凡且非函数依赖的多值依赖)=>

4NF(消除不为候选关键字所隐含的连接依赖)=> 

5NF。

 

投影分解
上面提到了投影分解方法,关系模式的规范化过程是通过投影分解来实现的。这种把低一级关系模式分解成若干高一级关系模式的投影分解不是唯一的,应在分解中注意满足三个条件:
1. 无损连接分解,分解后不丢失信息;
2. 分解后得的每一关系都是高一级范式,不要同级甚至低级分解;
3. 分解的个数最少,这是完美要求,应做到尽量少。

 

规范化的利弊
有一利必有一弊。规范化的优点是明显的。避免了大量的数据冗余,节省了空间,保持了数据的一致性,如果完全达到3NF,你不会在超过一个地方更改同一个值。如果你的记录经常的改变,这个优点回超过所有可能的缺点!
它最大的不利是,你把信息放置在不同的表中,增加了操作的难度,同时把多个表连接在一起的花费也是巨大的(节省了时间必然付出空间的代价,反之,节省了空间也必然付出时间的代价,时间和空间在计算机领域中是一个矛盾统一体,它们互相作用,对立统一)。因为表和表的连接操作是做两个关系的笛卡儿积(如果表一有n条记录,表二有m条记录,如果没有任何连接条件的话,连接在一起就是n*m条记录,其数量是不可承受的,毋宁说大量的表连接在一起了),必然会产生大量无用甚至无效的记录,性能的代价是巨大的。

 

非规范化(Denormalization)
即使你花费你所有的午休时间,作出一个完全规范化的数据库(你的大学教授可以证明),它仍然不是完美的。规范化设计所带来的性能问题可能你无法承受。如果出现这种情况,你就要准备进行非规范化了。非规范化就是你为了获得性能上的利益所进行的违反规范化规则的操作,并没有什么魔法在里面。它是一个性能利益分析,尝试和再尝试和不断的再评估过程。它也有很多方法,不过大部分都与实际应用有关系,包括复制属性,复制外来关键字,表合并,表重新组合等等,你可以根据实际的应用选择最有效的方法。

 

Ref:

http://mengxiaozhe.javaeye.com/blog/93175

http://dmt.w29.myhostadmin.net/Article/dnwl/200901/20090110210002.html

你可能感兴趣的:(数据)