标准化表示从你的数据存储中移去数据冗余(redundancy)的过程。如果数据库设计达到了完全的标准化,则把所有的表通过关键字连接在一起时,不会出现任何数据的复本(repetition)。标准化的优点是明显的,它避免了数据冗余,自然就节省了空间,也对数据的一致性(consistency)提供了根本的保障,杜绝了数据不一致的现象,同时也提高了效率。
第一范式(1NF;The First Normal Form)
属于第一范式的数据表有几个要求:
n 表中的每一个字段都是原子级的,不可以再分
n 每一行的记录没有重复
n 存在主属性,并且所有的非主属性都依赖于主属性
1NF存在几个问题:
n 数据冗余:通常一个项目需要多个员工参与与合作完成,因此项目信息被重复记录;这会导致更新异常,比如要修改一个项目名称,就需要同时修改多条记录的内容。
n 插入冗余:如果一个项目刚刚立项,还没有组建项目组,那么在插入记录时,员工编号一列就为空,但是因为员工编号属于主属性,主属性又不能是空值,所以这条记录就无法插入到数据库中,因此项目信息无法被记录。
n 插入异常:
第一范式是最低的规范化要求,第一范式要求数据表不能存在重复的记录,即存在一个关键字。1NF的第二个要求是每个字段都不可再分,即已经分到最小,关系数据库的定义就决定了数据库满足这一条。主关键字达到下面几个条件:
1.主关键字段在表中是唯一的
2.主关键字段中没有复本
3.主关键字段不能存在空值
4.每条记录都必须有一个主关键字
5.主关键字是关键字的最小子集
注:1NF含有主关键字,防止数据出现重复行。
第二范式(The Second Normal Form)
定义:如果一个关系属于1NF,且所有的非主关键字段都完全地依赖于主关键字,则称之为第二范式,简记为2NF。
为了说明问题现举一个例子来说明:有一个库房存储的库有四个字段(零件号码,仓库号码,零件数量,仓库地址),
这个库符合1NF,其中“零件号码”和“仓库号码”构成主关键字。
但是因为“仓库地址”只完全依赖与“仓库号码”,即只依赖于主关键字的一部分,所以它不符合2NF,
这样首先存在数据冗余,因为仓库数量可能不多。
其次,存在如果更改仓库地址时,如果漏改了某一记录,存在数据不一致性。
再次,如果某个仓库的零件出完了,那么这个仓库地址就丢失了,即这种关系不允许存在某个仓库中不放零件的情况。
我们可以用投影分解的方法消除部分依赖的情况,而使关系达到2NF的标准。
方法是从关系中分解出新的二维表,是每个二维表中所有的非关键字都完全依赖于各自的主关键字。
我们可以如下分解:分解成两个表(零件号码,仓库号码,零件数量)和(仓库号码,仓库地址)。
这样就完全符合2NF了。
注意:2NF条件是非主关键字段都完全地依赖于主关键字。
第三范式(The Third Normal Form)
定义:如果一个关系属于2NF,且每个非关键字不传递依赖于主关键字,这种关系是3NF。
从2NF中消除传递依赖,就是3NF。比如有一个表(姓名,工资等级,工资额),其中姓名是关键字,此关系符合2NF,但是因为工资等级决定工资额,这就叫传递依赖,它不符合3NF,
我们同样可以使用投影分解的办法分解成两个表:(姓名,工资等级),(工资等级,工资额)。
注:3NF就是在2NF的基础上,去除了传递依赖。
规范化的利弊
有一利必有一弊。规范化的优点是明显的。他避免了大量的数据冗余,节省了空间,保持了数据的一致性,如果完全达到3NF,你不会在超过一个地方更改同一个值。如果你的记录经常的改变,这个优点回超过所有可能的缺点!
它最大的不利是,你把信息放置在不同的表中,增加了操作的难度,同时把多个表连接在一起的花费也是巨大的(“时间空间互换理论”,此理论乃笔者杜撰,千万别拿出去当论据!节省了时间必然付出空间的代价,反之,节省了空间也必然付出时间的代价,时间和空间在计算机领域中是一个矛盾统一体,它们互相作用,对立统一)。因为表和表的连接操作是做两个关系的笛卡儿积(如果表一n条记录,表二m条记录,如果没有任何连接条件的话,连接在一起就是n*m条记录,其数量是不可承受的,毋宁说大量的表连接在一起了),必然会产生大量无用甚至无效的记录,性能的代价是巨大的。
非规范化(Denormalization)
即使你花费你所有的午休时间,作出一个完全规范化的数据库(你的大学教授可以证明),它仍然不是完美的。规范化设计所带来的性能问题可能你无法承受。如果出现这种情况,你就要准备进行非规范化了。非规范化就是你为了获得性能上的利益所进行的违反规范化规则的操作,并没有什么魔法在里面。它是一个性能利益分析,尝试和再尝试和不断的再评估过程。它也有很多方法,不过大部分都与实际应用有关系,包括复制属性,复制外来关键字,表合并,表重新组合等等,你可以根据实际的应用选择最有效的方法。