數據庫在應用程序中是必不可少的部分,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的記錄。
這樣,可達到兩個效果:一是更新永遠是實時同步,不會有誤;二是可減少存儲過程的調用頻率,可節省資源。
參考: