- 论坛徽章:
- 0
|
1. 主码相同
主码是关系数据库中每一个表的某个记录的主键值。分散的数据库归并过程中极大可能产生的问题是同一个表中有相同的主码。一般来说,由于实体的自然属性不能唯一标识实体,因此在进行系统设计时通常采用一个或几个可累加的数字型字段来标识该实体;而在数据库初始化时,通常给这几个字段的值是相同的(为空可为0),该字段组的值在数据库运行过程中不断累加。例如有一个客户资料表:customer(序号,姓名,性别,出生日期,其它客户信息……),主键为序号,即进入数据库的顺序,数据库初始化时customer表中无数据,当增加一个客户时,序号的值就自动加1,于是在该库中的客户的序号就从0一直可到计算机能表示的最大整数;同时另外一个公司的数据库中的客户序号也是从0开始一直可到计算机能表示的最大整数。当把这两个公司的数据库归并时,客户表中序号相同而发生冲突。由于序号相同而破坏了关系数据库规范化理论实体完整性[1]中的第三条:关系模型中的主码必须是唯一的,使得归并一定不能成功。因此,在归并过程中首先要消除主码相同的现象。
我们现在来分析产生主码相同的原因,随后针对不同原因采取相应的方法。产生主码相同的原因可归结为下列三点:
1)数据库结构设计的不合理
在进行数据库结构设计时,如果系统分析员没有考虑全面或者由于当时的管理方式的局限性而使数据库结构设计不合理,这很容易造成数据库归并时主码相同的现象。解决的方法有两种:
a)在表中加主键字段
b)把主码进行修改
2、触发器的存在
触发器的存在是产生主码相同的另一个主要原因。我们进行数据库归并的操作就是向表中插入数据的操作,因此引起主码相同的是插入事件而引起的触发器。例如在上述数据库是有一个订货单表order(分支机构号,货单序号,其它信息……)和一应付款表pay(分支机构号,货单序号,应付金额,应付日期,其它信息……),主键为分支机构号和货单序号,假设order表有一插入事件触发器ti_order,当往order表中插入一订货单记录时,ti_order就往pay表中插入一条应付款记录。进行数据库归并时,由于该触发器的存在,当往order表中load数据时,同时引发ti_order往pay表中插记录,这样就会有两条一样的pay记录。消除该类原因产生的主码相同现象的方法就是在load该表之前去掉该表的所有插入事件触发器,在load该表完成之后再加。
3)业务的交叉
业务的交叉发展,也是引起主码相同的主要原因之一。假设有两个分公司为了业务的交叉发展,在进行数据库初始化时都加上了对方的分支机构设置,当A公司的一个客户要在B公司进行业务时,B公司就在customer表中插入一客户资料记录,这时客户资料的主码为(A公司分支机构号,序号1,姓名a,性别a,其它信息a……),由于序号是从0开始累加的,在A公司的所有客户中也会存在一条这样的记录(A公司分支机构号,序号1,姓名b,性别b,其它信息b……),于是产生了主码相同而客户自然信息不同的客户资料。消除该类原因产生主码相同现象的方法是:在归并之前,各分公司的序号加上一个固定的值。例如上述情况,假设A分公司的客户序号在归并时最大为10000,那么我们首先把B公司中的A公司客户的序号都加上10001,同时修改相应的其它参照customer表的相应字段值。
2. 被参照的值不存在
数据库归并时第二个可能产生的问题是被参照的值不存在。一般来说,数据库中的各个表不是独立的而是相互有联系的,例如上述的订货单表order和应付款表pay,pay表中的(分支机构号,货单序号)元组值必须在order表中能存在,否则数据库管理系统对pay表进行参照完整性校验时就会报错。参照完整性是这样定义的[1]:若基本关系R中含有与另一个基本关系S的主码Ks相对应的属性组F(F称为R的外键),则对于R中的每个元组在F上的值必须为空值或者等于S中某个元组的主码值。
我们现在来分析一下被参照的值不存在的原因,然后针对原因给出解决的方法。产生被参照的值不存 在的原因主要可归纳为两点:
1)归并时表的顺序安排不合理
归并时各表的顺序至关重要。例如在归并order表之前归并pay表,那pay表中参照order表中的值都还没有进库,这样就产生了被参照的值不存在现象。解决该原因产生的被参照的值不存在现象的方法就是调整归并时表的顺序,上述例子中,如果我们先归并order表后归并pay表,则对pay表进行参照完整性校验时就会满足关系完整性约束。进行归并顺序调整的一般性原则是:被参照最多的最先归并,没有被参照的最后归并。
2)表之间的循环参照关系
由于表之间的循环参照关系产生的被参照的值不存在现象在归并的过程中不多但有时也存在。现假设该库中还有A、B、C、D四个表,其参照关系为:A参照B,B参照C,C参照D,D又参照A。对于循环参照关系,无论你把哪个表先归并,都会产生被参照的值不存在现象。解决的方法是破坏循环关系。我们把归并的顺序改为D、B、C、A,同时去掉D参照A的约束,在归并完A表的数据后再加上该约束。
3. Informix数据库归并程序
为了能查明归并时出错的地方,我们采用SQL语句来编写归并程序。Informix数据库归并的两条主要SQL命令为:
1)unload to a.txt select * from a
2)loadfrom a.txt insert into a
根据这两条命令,归并程序也分两个SQL程序,分别为unload.sq1和load.sq1,它们分别是把县支公司的所有业务数据卸下来和归并到主库中。unload.sql都是形如语句1)的sq1命令。load.sq1中除了语句2)外,还有删除参照约束条件、触发器和加上参照约束条件、触发器的语句。归并程序还包括一个辅助程序,用于对某些表的主码进行修改,同时修改相应的其它表的参照值,现把上述举例的数据库归并程序的两个SQL程序列如下:
unload.sq1:
unload to customer.txt select * from customer;
unload to crder.txt select * from order;
unload to pay.txt select * from pay;
unload to a.txt select * from A;
unload to b.txt select * from B;
unload to c.txt select * from C;
unload to d.txt select * from D;
……
load.sq1:
load from customer.txt insert into customer;
drop ti_order;
load from order.txt insert into order.txt;
create trigger ti_order insert on order referencing new as new_ins for each row
( insert into pay (new_ins.分支机构号,new_ins.订货单号,……));
load from pay.txt insert into pay;
drop constraint fk_D1;
load from d.txt insert D;
load from c.txt insert into C;
load from b.txt insert into B;
load from a.txt insert into A;
alter table D
add constraint foreign(i,j)referencing A(i,j)constraints fk_D1;
看看这个应该有点帮助 |
|