数据库在应用程序中是必不可少的部分,mysql是开源的,所以很多人它,mssql是微软的,用在windows平台上是非常方便的,所以也有很多人用它。现在问题来了,如何将这两个数据库同步,即数据内容保持完全一致。
MySQL Migration Toolkit是MySQL提供的开源GUI软件工具,可以针对Microsoft Access、Microsoft SQL Server、Oracle、MySQL、Sybase Server、MaxDB Database Server数据库向MySQL数据库迁移数据,这就解决了mssql同步到mysql的问题了;SQL Server迁移助手(SSMA)团队开发了针对MySQL的迁移助手Microsoft SQL Server Migration Assistant 2008 for MySQL。微软同时发布了其他三个迁移助手: SSMA for Access, SSMA for Oracle, and SSMA for Sybase (all v4.2),所以它可以解决mysql到mssql的问题,方法详见:MySQL到MsSQL的迁移工具——SSMA,实现了,结束。
……
开个玩笑,上面说的工具非常好用,可以留着备用。现在才是真正的问题:如何将这两个数据库实时同步(mysql到mssql),即数据内容实时保持完全一致。说白了,就是mysql插入(或修改、删除)一条记录,mssql也跟着同时插入(或修改、删除)该条记录,实时同步,不得有误。
问题
所谓mysql到mssql的实时同步数据。其要求是:
(1)当mysql数据库中插入一条记录,mssql数据库也同时插入对应记录;
(2)当mysql数据库中更新某些记录,mssql数据库也同时更新对应记录;
(3)当mysql数据库中删除某条记录,mssql数据库也同时删除对应记录;
这些记录变更的时间和方式都是随机的,不确定的,所以需要随时监测它的变化。同时,如下约定:
A. 在数据库同步之前,mysql和mssql数据库结构和内容完全一致;
B. 只对数据进行插入、更新和删除操作,不更改主键和结构。
分析
要实现数据库实时同步,解决方案一般有三种:一是编写程序来操作两个数据库,先将目标数据库删除,再根据原数据库进行重新生成目标数据库,但这种方法对于数据量大的数据库操作显然不可行;二是使用SQL中的触发器、存储过程和定时作业来完成实时同步;三是借助第三方的软件,如SyncNavigator,但综合经济性、稳定性和易维护性等因素,此方案慎用。
实现
(1)新建mysql临时和mssql临时数据库,数据结构与对应正式数据库相当,仅在每一个表中增加新字段OpType(用于记录数据修改的操作方式);
(2)在mysql数据库中建立触发器,作用是当mysql数据库中更改,mysql临时数据库相应表生成相应记录,并记录OpType字段(I表示插入记录,U表示修改记录,D表示删除记录);
(3)新建mysql临时数据库与mssql临时数据库之间的连接;
(4)在mssql临时数据库新建存储过程,当执行存储过程时,更新mssql临时数据库的内容,使之与mysql临时数据库内容完全一致,同时删除mysql临时数据库的内容;
(5)新建定时作业,定时调用mssql临时数据库中的存储过程;
(6)在mssql临时数据库建立触发器,根据OpType字段类型,更新mssql数据库的内容,同时删除mssql临时数据库的内容。
至此,实现了mysql数据库到mssql数据库的实时同步,其中,mysql临时数据库和mssql临时数据库只是过程数据,在同步完成后,数据表中的记录将被删除。这里所谓的实时,还取决于mssql中定时作业的计划。
Mssql连接mysql的方法
EXEC sp_addlinkedserver @server = 'MySQL', @srvproduct='MySql' , @provider = 'MSDASQL', @provstr = 'Driver={MySQL ODBC 5.2 UNICODE Driver}; Server=localhost; Database=mysql_temp; User=root; Password=****; Option=3;'
增加权限:
EXEC sp_addlinkedsrvlogin @rmtsrvname='MySql' , @useself='false' , @locallogin='sa' , @rmtuser='root' , @rmtpassword='****'
优化
由于实际数据库可能在极短时间内对一条记录进行多次频繁更新,为防止同步错误,可以两张临时表中再建立状态字段(IsUpdate)。具体操作方法:
(1)当mysql修改记录时,触发的mysql_temp表中的IsUpdate字段值标记为0;
(2)当存储过程调用时,将mysql_temp表中更新到mssql_temp的同时,将mysql_temp表中的IsUpdate字段值标记为1,并删除值为1的记录;(先更新值,再复制,最后删除,下同。)
(3)mssql_temp触发器运行时,除了将mssql_temp的记录更新到mssql外,还将删除mssql_temp表中IsUpdate字段值标记为2,并删除值为2的记录。
这样,可达到两个效果:一是更新永远是实时同步,不会有误;二是可减少存储过程的调用频率,可节省资源。
参考: