在数据库的设计阶段,数据库正规化过程中的一系列步骤指引我们分析和设计数据间的关系。本文向我们解释了为什么第三范式在某些时候并不是十分可行的,以及更倾向于一种混合的方法来实现数据库正规化的操作。
数据库组织过程将数据库正规化称之为指引我们分析和设计数据关系的一系列步骤,正规化的目的就是为了减少冗余数据,降低数据不一致相关性。
Dr. E. F. Codd最早提出了正规化的一系列准则。他提出的准则就是我们熟知的“范式”。这些范式表格是按序逐一建立的,从顶层的全局数据组织开始,然后考虑更细小的准则。
为了阐述这些表格的作用,让我们来看一个实例。某个电子表格中的数据字段是用来跟踪汽车销售情况的。我们将要分析表格中的数据并对数据表进行正规化操作。下表就是一个在分析中要使用的实例表结构。
第一范式表格:
下面将是操作过程的第一步。这一步的目标就是消除数据表格中的非原子型字段。使得在表格中的每个字段都是不可再分,并且表格具有唯一的主关键字,再另外为其它的相关数据创建一个表格。根据“非原子型”标准,我们查找哪些数据字段包含多个值,例如全名等。
通过观察数据表格,我们可以更改以下几处。首先,OwerName是一个字段,事实上我们可以将之拆分为owner first name 和last name 两个字段。其次,该数据表没有指定主关键字。TransactionNumber字段在数据表中是唯一的,因此我们可以指定TransactionNumber作为主关键字。结果如下:
第二个范式表格:
我将创建单独的表格来保存那些不断重复出现的数据。一旦创建这些表格,就可以使用外部键约束来反映表格间的关系。同时,表格中的每一个非主关键字字段就可以看作是描述主关键字的属性。在执行这条规则之前,表格必须已经严格按照第一个范式进行了处理,如下图:
在第一次范式表格上再进行第二次范式操作,操作的结果是我们得到了两个表。其中AutoSales表包含的是关于销售交易和顾客的信息,而AutoSales表包含的是交易中销售车辆的信息。就像你看到了那样,通过这样的操作,我们就不需要在第一种范式表格中某些字段的重复数据。
第三范式:
这是我对样例表格作的最后一次标准化操作。通过这次操作要达到的目的是消除表格中那些不完全函数依赖主关键字的字段。我们必须确保表格中的字段都是完全依赖于主关键字的。如下图:
当实施完第三范式操作后,将会产生四个表(事实理论上还可以得到五个表)。由于在Transactions表格中,顾客姓名字段并不是完全函数依赖于主关键字,所以我将它从Transactions 表中移去,并重新为它建立了一个AutoOwners表。在AutoOwners表中我创建了一个主关键字并通过它与Transactions表产生关联。
我们知道CarType字段与TransactionDetail表中的主关键字没有明确的依赖关系,但是VIN字段却与TransactionDetail表中的主关键字存在着这种依赖关系。由于CarType的依赖关联与VIN 数值,我单独创建了一个Automobiles表格,将VIN作为这个表格的主关键字。同样,CarType作为一项查询数据。事实上,我同样可以为它创建一个单独的表格,这里为了简化操作,就没有考虑。
正规化的一种替代方案
你是否总是按照第三范式的要求处理你的数据库呢?忠实的支持者们认为,按照第三范式的要求对数据库进行处理是十分重要,它将使得数据库从根本上和理论上都是一个合理的结构,并减少空数据和冗余数据,从而节省存储空间。
根据我的经验,依照第三范式建立的数据库并不是非常的实用。依照第三范式建立起的数据表在执行数据恢复操作时常常会失败,而数据库恢复恰恰是我们要经常进行的操作。通过完全规范化方法(大多数的数据库管理员认为通过第三范式建立的数据库是完全规范化的)产生的一个问题就是会得到许多的表格,所以当进行查询操作时就必须要使用更多的连接语句。这就会给开发人员带来更多的不变,并且导致数据查询的时间增多。
我认为最好的解决方法就是采用折中方案。我一般会按照类似第三范式的要求来设计数据库。在这类数据库中,着重于数据库的查询,并且在必要的时候可以反正规化操作。这种所谓的反正规化操作使我们节省了大量宝贵的CPU资源。当然,我们也要为性能的提升付出相应的代价,代价就是你要使用更多的数据空间(数据冗余的存在)。