蜜果私塾:如何进行异构数据库同步(下篇)
版权所有,转载请注明出处:http://www.blogjava.net/amigoxie/archive/2011/07/24/354917.html
文:阿蜜果
日期:2011-7-24
上篇:《如何进行异构数据库同步(上篇)》
1、详细设计
1.1 SQL语句通用解析程序
首先需要一个通用的“SQL语句通用解析程序”,因为异构数据库的大部分表都与另外的表有一一对应的关系,该解析程序用于对这些一一对应的表进行处理。
表与表之间的对应关系基于上篇提到的整理的Excel文档,“SQL语句通用解析程序”如何读取对应关系对收到的INSERT、UPDATE和DELETE语句进行处理呢?笔者采用的是将对应关系写入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" />
另外,还有一些字段本端没有,对端具有并且有点还是必填字段,并且对端的这些字段需要填写固定的值,因此在INSERT、UPDATE和DELETE语句都需要进行特别的操作,参考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)、执行的操作名(INSERT、UPDATE还是DELETE),根据这些信息读取配置文件信息,决定是调用“1.1 SQL语句通用解析程序”进行处理,如果不是存在一对一对应关系的表,扔给配置的指定业务进行特别处理。
该程序的主要功能如下:
(1)接收SQL语句:只接收需要同步的表的INSERT、UPDATE和DELETE语句,SELECT语句直接丢弃;
(2)分发SQL语句:将语句分发给不同程序进行处理,解析接收到的SQL语句的表名和操作名称,决定分发给通用解析进行处理还是特定解析程序进行处理。
需要关注的问题:当多条SQL语句并发发送过来时,是启动多个独立的自动机处理,还是将语句放入队列中,依次出队列进行处理,还是采用其它方式进行处理呢?每条SQL语句启动独立的自动机处理效率最高,但是也存在问题:因为多条语句是竞争操作,如果操作的是同样的记录但做相反操作时怎么办?这些都是开发人员需要考虑到的问题。
1.3 SQL单个表特定解析程序
在上篇中提到,并不是所有的表在两端有一一对应的表,对于一些本端一个表对应对端数据库多个表,或者本端多个表对应对端一个表的情况,通用解析程序不好处理这些语句,可将这些表采用特定的解析程序进行处理。
对于一个表对应多个表的情况,可能一条INSERT语句对应对端数据库多条INSERT或UPDATE语句。
对于多个表对应一个表的情况,一条INSERT语句可能对应对方的一条INSERT语句或UPDATE语句。
1.4 带事务的操作
像注册等流程,要严格保证事务,因此采用新旧系统提供接口(例如http接口或SOAP接口等)的方式,当某一端调用注册流程成功后,调用对端系统提供的注册的接口完成操作。
因为这种操作并不多,所以并不需要太多的工作量。
1.5 数据校验程序
要定期(一般是一天)对两边数据进行校验,对一些错误的数据及时的更正,进行数据校验首先要确定哪些东西需要进行数据校验,接着有针对性的进行核对。
2、扩展阅读
2.1 数据同步方法
对象变化是数据同步的基础,它直接决定了数据同步的更新方式和选时方式,所以数据同步常常按照变化捕获的不同进行分类,一般归结于如下集中基本方法:
(1)基于快照法:快照是数据库中存储对象在某一时刻的即时映像。通过同步对象定义一个快照或采用类似方法,可以将它的当前映像作为更新副本的内容。
(2)基于触发器法:在源数据库为同步对象创建相应的触发器,当同步对象进行INSERT、UPDATE和DELETE等DML命令时,触发器被唤醒,将变化传播到目标数据库。
(3)基于日志法:数据库日志作为维护数据库完整性的数据库恢复的重要工具,其中已经包含了全部成功提交的操作记录信息。该方法通过分析数据库日志的信息来捕获同步对象的变化序列。
(4)基于API法:一些小型的数据库和非关系型数据库没有触发器和日志机制,可以在应用程序和数据库之间引用一层中间件,由它提供一系列API,在API上来完成应用程序对数据库修改的同时,记录同步对象的变化序列。
(5)基于影子表法:许多情况下,源程序无须了解同步对象的每一个操作,只要知道最后总共发生了什么变化就够了。因此,可以在初始化时为同步对象表T建立一个影子表S,作为一份当时的拷贝,以后通过在适当时机通过比较当前T和S的内容获取净变化信息。
(6)基于控制表变化法:就是为每个要同步的表创建一个控制表C,C包含了主键字段Pk和一些控制信息字段,当T中某个字段发生改变时,C中同主键Pk的记录也随即被修改。这一过程通常可以通过触发器实现,到时候只需根据C就知道T中的变化信息。
3、附录
(1)《异构数据库同步问题研究》:
http://wenku.baidu.com/view/d3b283bff121dd36a32d8293.html
posted on 2011-07-24 13:05
阿蜜果 阅读(2314)
评论(2) 编辑 收藏 所属分类:
解决方案