蜜果私塾:如何進行異構數據庫同步(上篇)
版權所有,轉載請注明出處:http://www.tkk7.com/amigoxie/archive/2011/07/23/354906.html
文:阿蜜果
日期:2011-7-23
下篇:《如何進行異構數據庫同步(下篇)》
1、簡介
最近一陣子筆者在進行完成同樣功能的兩套異構數據庫系統的同步工作,有一些心得體會分享給大家,歡迎技術同仁拍磚。
該項目有一個運行若干年(5~10年)的舊系統,采用的是SQL Server數據庫,因為舊平臺功能較弱,所以所有對數據庫的訪問操作都通過存儲過程進行操作。
新系統采用筆者公司的平臺,應客戶需求采用Oracle數據庫,完成的功能與舊系統基本相同,但表設計與原有系統不同,有些表對應舊系統中的一張表,但字段名稱等大都不一樣。另外還有新系統中一張表對應舊系統中多張小表的情況,也有新系統中多個表對應舊系統中多張表的情況。新系統較少依賴數據庫,數據庫操作都在業務邏輯層完成。
因為舊系統在全國幾十個點上運行,而新系統全部替換舊系統需要比較長的時間,該項目采用的是按地區進行逐步替換的原則,所以涉及到需要在兩種不同數據庫類型、不同數據庫結構的異構數據庫進行同步。
2、重要術語
2.1 異構數據庫
異構數據庫系統是相關的多個數據庫系統的集合,可以實現數據的共享和透明訪問,每個數據庫系統在加入異構數據庫系統之前本身就已經存在,擁有自己的DBMS。異構數據庫的各個組成部分具有自身的自治性,實現數據共享的同時,每個數據庫系統仍保有自己的應用特性、完整性控制和安全性控制。
可以是同為關系型數據庫系統的Oracle、 SQL Server等,也可以是不同數據模型的數據庫,如關系、模式、層次、網絡、面向對象,函數型數據庫共同組成一個異構數據庫系統。
2.2 數據捕獲
數據的捕獲是數據庫同步的基礎,變化數據的捕獲主要有基于快照法、基于觸發器法、基于日志法、基于API法、影子表法和控制表變化法。基于快照法效率比較低一般不能用于同步,可使用基于觸發器法、基于日志法或基于API法和控制表變化法進行變化數據的捕獲。
舊系統的數據庫操作都是通過存儲過程,所以可將存儲過程作為數據捕獲點。
新系統可采用筆者公司平臺底層提供了同步程序,該程序能將某個Linux用戶本平臺進程下所有對指定表(需要同步的表)的所有INSERT、UPDATE和DELETE語句都捕獲到,并同步給另一個用戶下的同步數據接收進程,該進程能指定接收到同步數據時進行的操作,例如寫文件、調用指定的業務進行處理等。
3、同步方案
3.1 需要同步的內容
3.1.1 確認哪些SQL需要同步
在數據庫表創建以后,有SELECT、INSERT、UPDATE和DELETE四種操作的語句,因為SELECT語句不會影響表數據的改變,所以只需要INSERT、UPDATE和DELETE操作進行同步。
3.1.2 確認哪些表需要同步
并不是所有的表都需要進行同步的,例如如下表就不需要同步:
(1)在系統創建之初需要導入數據,后期基本不需要改動或絕少改動的表:這些表的數據基本只需要在新系統初期將數據導入即可。
(2)一方系統具有,另一方不具有的功能對應的表:例如新系統加上了一些額外的功能,而舊系統沒有,這些表不需要同步。
3.1.3 確認異構數據庫之間的表和字段的對應
這個是異構數據庫編碼之前最耗費時間的工作,也是最重要的工作,因為只有嚴格對應,才能使兩者同步后數據庫在同步數據后不管用哪套系統都能完成同樣的工作。
首先,要對新舊系統中的近50張表找出對應關系:某一張表在對方有一一對應的表?還是對應對方多張表?還是只是對應對方表的一部分?
接著,需要找出字段的對應關系,字段名稱是否相同?字段類型是否相同?一個字段是否對應對方表的多個字段?
筆者在Excel表格中列出了所有表與對方表結構的對應關系,這個表格很重要,是后面無論采用何種同步方案都需要用到的同步的依據。
3.2 可選方案
3.2.1 編寫觸發器進行同步
當數據庫為同步對象創建相應的觸發器,當對同步對象進行INSERT、UPDATE和DELETE等DML(Data Manipulation Language)操作時,觸發器被喚醒,將變換傳播到目標數據庫。
采用此種方式時,需要在兩邊的數據庫中都創建對需要同步的每個表的INSERT、UPADTE和DELETE操作的三個觸發器,當源表發生INSERT、UPDATE和DELETE操作時觸發器被啟動。因此若兩邊都有50個需要同步的表,需要編寫的觸發器個數為:(50+50)*3 = 300(個)。
采用該種方式的缺點是:
(1) 需要為每個需要同步的表編寫三個觸發器,工作量巨大;
(2) 觸發器具有不容易排錯、可移植性差、占用資源大等缺點;
(3) 代碼可復用性不好。
3.2.2 按系統操作同步
按系統操作同步就是在所有進行數據庫更新操作的地方都將其轉換成對方的數據庫操作進行,例如在新系統進行注冊操作(可能涉及到5、6個表進行操作)時,轉換為對方的注冊操作。
這種同步方式的缺點在于:
(1)不通用:在每加一個系統操作或做一些小改動時,都需要對代碼進行修改;
(2)代碼耦合度高:需要在所有操作的地方進行處理,轉換成對方的SQL語句,代碼耦合度非常高;
(3)工作量很大:需要對所有兩邊的操作進行一次手工“轉譯”操作,工作量很大。
3.2.3 按數據庫表操作同步
按表操作同步的“原子”是對單個表的的INSERT、UPDATE和DELETE操作,它并不關注操作,例如:如果一個注冊操作對應5個INSERT操作、2個UPDATE操作,它將其作為7個原子操作依次處理,并不對這些SQL進行關聯。
這種同步方式的優點在于:
(1)相對比較通用:有一些比較簡單的對應關系的表,例如只是因為字段名稱、表名和字段個數等不同而需要進行同步的表可交給“SQL語句解析器通用程序”進行處理,對于某些復雜的表才需要進行單獨編寫業務來進行轉換處理;
(2)代碼耦合度比較低:只需要捕獲對同步的表的INSERT、UPDATE和DELETE操作的語句,基本不需要在代碼中加入對同步的處理。舊系統中不需要在上層進行處理,在存儲過程中相關語句前處理同步即可。新系統只需要在同步接收進程中指定需要處理的業務即可。
推薦使用該同步方式。
3.3 難點問題
3.3.1 自增主鍵
當表的主鍵為自增序列號時,在插入時并不指定該字段的值,在某一方插入后,轉換為對方的SQL語句后,插入對方的數據庫,很大可能兩邊的這條記錄的主鍵ID不一致。在根據自增序列號進行這條記錄的update和delete操作時,因為兩邊同一條記錄的id不一樣,很大可能導致刪除或更新的記錄并不是想要進行刪除或更新的記錄。
因此,在系統中盡量少用自增序列號主鍵,若能找到某幾個字段作為復合主鍵,可進行修改,萬一找不到,可采用字符類型的唯一標識號,例如:時間+自動機號+若干位隨機數數,在INSERT操作時指定該主鍵的值。
不過,一些只進行INSERT操作的表,例如未接來電表采用自增序列號暫時也不用遇到什么問題。在筆者所遇到的平臺中,新系統基本去除了自增主鍵,舊系統涉及自增主鍵的表并不太多,而且基本都能找到表中其它的2、3個字段作為唯一主鍵。
3.3.2 事務問題
無法實現一些帶事務的操作。例如注冊等流程,因為采用按照數據庫操作進行同步,注冊操作被分解成多個原子操作,只能當成單個多條SQL語句單獨進行處理。
需要事務的操作并不多,可將這些操作改成采用“按系統操作同步”,例如當舊系統進行注冊流程中,調用新系統提供的接口,由接口程序也進行一個在新Oracle庫的注冊流程。
3.3.3 定期數據校驗
數據校驗也是異構數據庫的一個重要問題,進行一段時間的同步后,怎么能保證兩邊的數據庫是同步的?數據校驗的周期如何,是一天,幾天,還是?
進行數據校驗首先要確定校驗指標,最簡單的校驗指標是重要表的數據量是否相等,另外就是檢查表里面的數據是否一致,是否能保證能完成同樣的功能,可采用抽查機制等,這些工作不可能靠手工完成,因此需要提供數據校驗的程序。數據校驗的周期應該是可配置的。
3.3.4 日志記錄
在進行同步的過程中,有可能因為各種原因導致轉換為對方的數據庫語句后執行失敗,為了日后進行處理和分析,進行錯誤日志的記錄也是非常必要的。
posted on 2011-07-23 22:37
阿蜜果 閱讀(3578)
評論(0) 編輯 收藏 所屬分類:
解決方案