(转)如何进行异构数据库同步(下篇)

1、详细设计

1.1 SQL语句通用解析程序

首先需要一个通用的“SQL语句通用解析程序”,因为异构数据库的大部分表都与另外的表有一一对应的关系,该解析程序用于对这些一一对应的表进行处理。

表与表之间的对应关系基于上篇提到的整理的Excel文档,“SQL语句通用解析程序”如何读取对应关系对收到的INSERTUPDATEDELETE语句进行处理呢?笔者采用的是将对应关系写入XML文档中,当然也可以采用另外的方式。

参考XML格式如下(Oracle 新系统 ->  SQL Server旧系统):

< table  name ="freephone"  partyName ="PLAT_FreePhone"  fieldCount ="8" >
     
< field  name ="Phone"  partyName ="Phone"  primary ="true"   />
     
< field  name ="ProductID"  type ="varchar"  partyName ="ProductID"  partyType ="int"   />
     
< field  name ="AreaId"  partyName =""   />
     
< field  name ="Effect"  partyName =""   />
     
< field  name ="EffectLess"  partyName =""   />
     
< field  name ="Addtime"  type ="varchar"  partyName ="AddTime"  partyType ="datetime"  partyValue />
     
< field  name ="Operator"  partyName ="Operator"   />
     
< field  name ="Remark"  partyName ="Remark"   />
 
</ table >

当一方对freephone表操作的INSERT语句:

insert   into  freephone (Phone, ProductID, AreaId, Effect, EffectLess, Addtime, Operator, Remark) values (‘ 13122223333 ’,‘ 003 ’, 25 ,‘ 20110724000000 ’,‘ 20111024235959 ’,‘ 20110702409000000 ’, ‘amigo’, ‘amigo  add !’)

根据上面XML配置和通用解析程序的处理,对应对方的新的SQL语句为:

INSERT   INTO  PLAT_FreePhone(Phone, ProductID, AddTime, Operator, Remark)  values (‘ 13122223333 ’,  3 GETDATE (), ‘amigo’, ‘amigo  add !’)

再看一条UPDATE语句:

update  freephone  set  ProductID = 004 ’, AreaId = 26   where  Phone = 13122223333

转换为对方的语句为:

update  PLAT_FreePhone  set  ProductID = 4   where  Phone = 13122223333

另外除了如上所演示的简单的类型不同、字段名称不同,有些字段在对方没有外,有时候有些字段还需要一定的转换,例如在一方存储的limited字符串是二进制方式,例如111111,而对方存储的是二进制对应的十进制的值,再例如,一方存储的是6位的时间(时分秒),而对方存储的只是4位的时间(时分),那么可做一次自定义的substr操作。

看另一个参考的XML实例:

< table  name ="phonelimited"  partyName ="PLAT_PhoneLimited"  fieldCount ="6" >
    
< field  name ="Phonenumber"  partyName ="Phone"  primary ="true"   />
    
< field  name ="AreaId"  type ="int"  partyName ="AreaID"  partyType ="int"   />
    
< field  name ="Limited"  type ="varchar"  partyName ="Limited"  partyType ="int"  function ="binToDec"   />
    
< field  name ="AddTime"  type ="varchar"  partyName ="AddTime"  partyType ="datetime"   />
    
< field  name ="Operator"  partyName ="Operator"   />
    
< field  name ="Remark"  partyName ="Remark"   />
</ table >

其中:function="binToDec"表示需要进行一次二进制到十进制的转换,一方的如下语句:

insert   into  phonelimited(Phonenumber, AreaId, Limited)  values (‘ 13122223333 ’,  25 , ‘ 10110 ’)

转换成对方的INSERT语句如下:

insert   into  PLAT_PhoneLimited(Phone, AreaID, Limited)  values (‘ 13122223333 ’,  25 22 )

需要做取字串操作的参考定义如下:

< field  name ="StartTime"  length ="6"  partyName ="OpenTime"  partyLength ="4"  function ="substr"   />

另外,还有一些字段本端没有,对端具有并且有点还是必填字段,并且对端的这些字段需要填写固定的值,因此在INSERTUPDATEDELETE语句都需要进行特别的操作,参考XML定义如下:

……
< insert  fieldCount ="2" >
    
< field  name ="Node"  value ="0"   />
    
< field  name ="Key"  value =""   />
</ insert >
< update  condition ="and Node=0 and key=''"   />
< delete  condition ="and Node=0 and key=''"   />
……

1.2 SQL语句接收器程序

      异构数据库的SQL语句传过来时,需要一个SQL语句接收器程序,该接收器解析该语句操作的表名(例如phonelimited)、执行的操作名(INSERTUPDATE还是DELETE),根据这些信息读取配置文件信息,决定是调用“1.1 SQL语句通用解析程序”进行处理,如果不是存在一对一对应关系的表,扔给配置的指定业务进行特别处理。

      该程序的主要功能如下:

1)接收SQL语句:只接收需要同步的表的INSERTUPDATEDELETE语句,SELECT语句直接丢弃;

    2)分发SQL语句:将语句分发给不同程序进行处理,解析接收到的SQL语句的表名和操作名称,决定分发给通用解析进行处理还是特定解析程序进行处理。

         需要关注的问题:当多条SQL语句并发发送过来时,是启动多个独立的自动机处理,还是将语句放入队列中,依次出队列进行处理,还是采用其它方式进行处理呢?每条SQL语句启动独立的自动机处理效率最高,但是也存在问题:因为多条语句是竞争操作,如果操作的是同样的记录但做相反操作时怎么办?这些都是开发人员需要考虑到的问题。

1.3 SQL单个表特定解析程序

         在上篇中提到,并不是所有的表在两端有一一对应的表,对于一些本端一个表对应对端数据库多个表,或者本端多个表对应对端一个表的情况,通用解析程序不好处理这些语句,可将这些表采用特定的解析程序进行处理。

         对于一个表对应多个表的情况,可能一条INSERT语句对应对端数据库多条INSERTUPDATE语句。

         对于多个表对应一个表的情况,一条INSERT语句可能对应对方的一条INSERT语句或UPDATE语句。

1.4 带事务的操作

         像注册等流程,要严格保证事务,因此采用新旧系统提供接口(例如http接口或SOAP接口等)的方式,当某一端调用注册流程成功后,调用对端系统提供的注册的接口完成操作。

         因为这种操作并不多,所以并不需要太多的工作量。

1.5 数据校验程序

         要定期(一般是一天)对两边数据进行校验,对一些错误的数据及时的更正,进行数据校验首先要确定哪些东西需要进行数据校验,接着有针对性的进行核对。

2、扩展阅读

2.1 数据同步方法

对象变化是数据同步的基础,它直接决定了数据同步的更新方式和选时方式,所以数据同步常常按照变化捕获的不同进行分类,一般归结于如下集中基本方法:

1)基于快照法:快照是数据库中存储对象在某一时刻的即时映像。通过同步对象定义一个快照或采用类似方法,可以将它的当前映像作为更新副本的内容。

2)基于触发器法:在源数据库为同步对象创建相应的触发器,当同步对象进行INSERTUPDATEDELETEDML命令时,触发器被唤醒,将变化传播到目标数据库。

3)基于日志法:数据库日志作为维护数据库完整性的数据库恢复的重要工具,其中已经包含了全部成功提交的操作记录信息。该方法通过分析数据库日志的信息来捕获同步对象的变化序列。

4)基于API:一些小型的数据库和非关系型数据库没有触发器和日志机制,可以在应用程序和数据库之间引用一层中间件,由它提供一系列API,在API上来完成应用程序对数据库修改的同时,记录同步对象的变化序列。

5)基于影子表法:许多情况下,源程序无须了解同步对象的每一个操作,只要知道最后总共发生了什么变化就够了。因此,可以在初始化时为同步对象表T建立一个影子表S,作为一份当时的拷贝,以后通过在适当时机通过比较当前TS的内容获取净变化信息。

6)基于控制表变化法:就是为每个要同步的表创建一个控制表CC包含了主键字段Pk和一些控制信息字段,当T中某个字段发生改变时,C中同主键Pk的记录也随即被修改。这一过程通常可以通过触发器实现,到时候只需根据C就知道T中的变化信息。

 

3、附录

1)《异构数据库同步问题研究》:

http://wenku.baidu.com/view/d3b283bff121dd36a32d8293.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值