3.1.1 关系数据库设计缺陷

如何建立一个好的关系数据库模型呢?在解决如何建立一个好的关系数据库模型之前,我们先通过一个例子来看看某些不恰当的关系模型可能导致的问题。

设有一个“员工信息表”关系如下:

员工信息表[员工姓名,性别,政治面貌,籍贯……社会关系(与本人关系,姓名,工作单位),本人学习简历(起始至终止年月,所在单位,证明人)]

表3.1是上述“员工”关系的一个实例(只给出部分数据)。

表3.1“员工”关系的一个实例

从表3.1中可以看出:“社会关系”和“本人学习简历”两个数据元素又各自分别包含3个数据元素。这样使得同一员工的姓名、性别、政治面貌和籍贯等数据元素的值在关系中的多个记录中重复存储,产生了大量的数据冗余。同时,数据的重复存储会给更新带来麻烦。例如,如果某个员工的政治面貌发生改变,则关系中所有有关该员工的记录都要更改,如有一个不改就会导致数据的不一致。除此之外,设计不好的关系还会带来其他一些异常情况(如插入、删除异常等)。

如有另外一个关系“员工-项目”如下:

员工-项目(工号,姓名,职务,职称,项目编号,参与项目名称,项目负责人,承担任务,客户评价)

在这个关系中,只有根据员工的工号和参与的项目编号才能确定某员工在某个项目中承担的任务。这样,如果新承接了一个项目,而尚未确定参与的员工,则主关键字属性“工号”取值为空,但关键字是不允许出现空值的。如此,该项目诸如项目负责人之类的信息就无法存入数据库,同时暂时未参与任何项目的员工信息也无法存入数据库,即存在插入异常。

另外,一个项目完成后,删除该项目记录,则参与该项目的员工相关信息也被删掉了,即存在删除异常。

这些异常的产生主要是因为关系模式的结构,即关系中的属性之间存在过多的数据依赖关系。也就是说,关系中除了所有属性对主关键字属性的数据依赖以外,还存在着别的依赖关系。

在现实世界中,任何一个实体或实体的属性之间都存在一定的联系。如“员工信息表”中假设没有重名现象,则员工姓名“张楠”决定了他的性别、政治面貌等属性值;员工姓名“张楠”和与本人关系“父亲”值决定了张楠父亲的姓名、工作单位;员工姓名“张楠”和“1988/09—1992/07”值决定了张楠的所在单位及证明人。这些数据元素之间的依赖关系表示如下:

员工姓名→性别;员工姓名→政治面貌;员工姓名→政治面貌;员工姓名+与本人关系→姓名;员工姓名+与本人关系→工作单位;员工姓名+起始至终止年月→所在单位;员工姓名+起始至终止年月→证明人

将表3-1中的关系模式分解成3个新的关系模式:

(1)员工(姓名,性别,政治面貌,籍贯);

(2)员工社会关系(员工姓名,与本人关系,工作单位);

(3)员工学习简历(员工姓名,起始至终止年月,所在单位,证明人)。

可见,新的关系模式使上述的存储异常等问题都不存在了。这样的分解将更加符合现实世界的客观情况。所以,为了避免出现数据冗余、更新异常、插入异常和删除异常等情况,就要对关系模型进行合理分解,即进行关系模型的规范化。

结合以上内容,规范化的目的可以概括为以下四点:

(1)把关系中的每一个数据项都转换成一个不能再分的基本项;

(2)消除冗余,并使关系的检索简化;

(3)消除数据在进行插入、修改和删除时的异常情况;

(4)关系模型灵活,易于使用非过程化的高级查询语言进行查询。