posts - 297,  comments - 1618,  trackbacks - 0

          蜜果私塾:如何進(jìn)行異構(gòu)數(shù)據(jù)庫(kù)同步(上篇)

          版權(quán)所有,轉(zhuǎn)載請(qǐng)注明出處:http://www.aygfsteel.com/amigoxie/archive/2011/07/23/354906.html
          文:阿蜜果

          日期:2011-7-23
          下篇:《如何進(jìn)行異構(gòu)數(shù)據(jù)庫(kù)同步(下篇)》

          1、簡(jiǎn)介

          最近一陣子筆者在進(jìn)行完成同樣功能的兩套異構(gòu)數(shù)據(jù)庫(kù)系統(tǒng)的同步工作,有一些心得體會(huì)分享給大家,歡迎技術(shù)同仁拍磚。

          該項(xiàng)目有一個(gè)運(yùn)行若干年(510年)的舊系統(tǒng),采用的是SQL Server數(shù)據(jù)庫(kù),因?yàn)榕f平臺(tái)功能較弱,所以所有對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)操作都通過(guò)存儲(chǔ)過(guò)程進(jìn)行操作。

          新系統(tǒng)采用筆者公司的平臺(tái),應(yīng)客戶需求采用Oracle數(shù)據(jù)庫(kù),完成的功能與舊系統(tǒng)基本相同,但表設(shè)計(jì)與原有系統(tǒng)不同,有些表對(duì)應(yīng)舊系統(tǒng)中的一張表,但字段名稱等大都不一樣。另外還有新系統(tǒng)中一張表對(duì)應(yīng)舊系統(tǒng)中多張小表的情況,也有新系統(tǒng)中多個(gè)表對(duì)應(yīng)舊系統(tǒng)中多張表的情況。新系統(tǒng)較少依賴數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)操作都在業(yè)務(wù)邏輯層完成。

          因?yàn)榕f系統(tǒng)在全國(guó)幾十個(gè)點(diǎn)上運(yùn)行,而新系統(tǒng)全部替換舊系統(tǒng)需要比較長(zhǎng)的時(shí)間,該項(xiàng)目采用的是按地區(qū)進(jìn)行逐步替換的原則,所以涉及到需要在兩種不同數(shù)據(jù)庫(kù)類型、不同數(shù)據(jù)庫(kù)結(jié)構(gòu)的異構(gòu)數(shù)據(jù)庫(kù)進(jìn)行同步。

          2、重要術(shù)語(yǔ)

          2.1 異構(gòu)數(shù)據(jù)庫(kù)

          異構(gòu)數(shù)據(jù)庫(kù)系統(tǒng)是相關(guān)的多個(gè)數(shù)據(jù)庫(kù)系統(tǒng)的集合,可以實(shí)現(xiàn)數(shù)據(jù)的共享和透明訪問(wèn),每個(gè)數(shù)據(jù)庫(kù)系統(tǒng)在加入異構(gòu)數(shù)據(jù)庫(kù)系統(tǒng)之前本身就已經(jīng)存在,擁有自己的DBMS。異構(gòu)數(shù)據(jù)庫(kù)的各個(gè)組成部分具有自身的自治性,實(shí)現(xiàn)數(shù)據(jù)共享的同時(shí),每個(gè)數(shù)據(jù)庫(kù)系統(tǒng)仍保有自己的應(yīng)用特性、完整性控制和安全性控制。

          可以是同為關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)的Oracle SQL Server等,也可以是不同數(shù)據(jù)模型的數(shù)據(jù)庫(kù),如關(guān)系、模式、層次、網(wǎng)絡(luò)、面向?qū)ο?,函?shù)型數(shù)據(jù)庫(kù)共同組成一個(gè)異構(gòu)數(shù)據(jù)庫(kù)系統(tǒng)。

          2.2 數(shù)據(jù)捕獲

          數(shù)據(jù)的捕獲是數(shù)據(jù)庫(kù)同步的基礎(chǔ),變化數(shù)據(jù)的捕獲主要有基于快照法、基于觸發(fā)器法、基于日志法、基于API法、影子表法和控制表變化法?;诳煺辗ㄐ时容^低一般不能用于同步,可使用基于觸發(fā)器法、基于日志法或基于API法和控制表變化法進(jìn)行變化數(shù)據(jù)的捕獲。

          舊系統(tǒng)的數(shù)據(jù)庫(kù)操作都是通過(guò)存儲(chǔ)過(guò)程,所以可將存儲(chǔ)過(guò)程作為數(shù)據(jù)捕獲點(diǎn)。

          新系統(tǒng)可采用筆者公司平臺(tái)底層提供了同步程序,該程序能將某個(gè)Linux用戶本平臺(tái)進(jìn)程下所有對(duì)指定表(需要同步的表)的所有INSERTUPDATEDELETE語(yǔ)句都捕獲到,并同步給另一個(gè)用戶下的同步數(shù)據(jù)接收進(jìn)程,該進(jìn)程能指定接收到同步數(shù)據(jù)時(shí)進(jìn)行的操作,例如寫(xiě)文件、調(diào)用指定的業(yè)務(wù)進(jìn)行處理等。

          3、同步方案

          3.1 需要同步的內(nèi)容

          3.1.1 確認(rèn)哪些SQL需要同步

          在數(shù)據(jù)庫(kù)表創(chuàng)建以后,有SELECTINSERT、UPDATEDELETE四種操作的語(yǔ)句,因?yàn)?/span>SELECT語(yǔ)句不會(huì)影響表數(shù)據(jù)的改變,所以只需要INSERT、UPDATEDELETE操作進(jìn)行同步。

          3.1.2 確認(rèn)哪些表需要同步

          并不是所有的表都需要進(jìn)行同步的,例如如下表就不需要同步:

          1)在系統(tǒng)創(chuàng)建之初需要導(dǎo)入數(shù)據(jù),后期基本不需要改動(dòng)或絕少改動(dòng)的表:這些表的數(shù)據(jù)基本只需要在新系統(tǒng)初期將數(shù)據(jù)導(dǎo)入即可。

          2)一方系統(tǒng)具有,另一方不具有的功能對(duì)應(yīng)的表:例如新系統(tǒng)加上了一些額外的功能,而舊系統(tǒng)沒(méi)有,這些表不需要同步。

          3.1.3 確認(rèn)異構(gòu)數(shù)據(jù)庫(kù)之間的表和字段的對(duì)應(yīng)

          這個(gè)是異構(gòu)數(shù)據(jù)庫(kù)編碼之前最耗費(fèi)時(shí)間的工作,也是最重要的工作,因?yàn)橹挥袊?yán)格對(duì)應(yīng),才能使兩者同步后數(shù)據(jù)庫(kù)在同步數(shù)據(jù)后不管用哪套系統(tǒng)都能完成同樣的工作。

          首先,要對(duì)新舊系統(tǒng)中的近50張表找出對(duì)應(yīng)關(guān)系:某一張表在對(duì)方有一一對(duì)應(yīng)的表?還是對(duì)應(yīng)對(duì)方多張表?還是只是對(duì)應(yīng)對(duì)方表的一部分?

          接著,需要找出字段的對(duì)應(yīng)關(guān)系,字段名稱是否相同?字段類型是否相同?一個(gè)字段是否對(duì)應(yīng)對(duì)方表的多個(gè)字段?

          筆者在Excel表格中列出了所有表與對(duì)方表結(jié)構(gòu)的對(duì)應(yīng)關(guān)系,這個(gè)表格很重要,是后面無(wú)論采用何種同步方案都需要用到的同步的依據(jù)。

          3.2 可選方案

          3.2.1 編寫(xiě)觸發(fā)器進(jìn)行同步

           當(dāng)數(shù)據(jù)庫(kù)為同步對(duì)象創(chuàng)建相應(yīng)的觸發(fā)器,當(dāng)對(duì)同步對(duì)象進(jìn)行INSERT、UPDATEDELETEDMLData Manipulation Language)操作時(shí),觸發(fā)器被喚醒,將變換傳播到目標(biāo)數(shù)據(jù)庫(kù)。

           采用此種方式時(shí),需要在兩邊的數(shù)據(jù)庫(kù)中都創(chuàng)建對(duì)需要同步的每個(gè)表的INSERT、UPADTEDELETE操作的三個(gè)觸發(fā)器,當(dāng)源表發(fā)生INSERT、UPDATEDELETE操作時(shí)觸發(fā)器被啟動(dòng)。因此若兩邊都有50個(gè)需要同步的表,需要編寫(xiě)的觸發(fā)器個(gè)數(shù)為:(50+50)*3 = 300(個(gè))。

          采用該種方式的缺點(diǎn)是:

          (1)       需要為每個(gè)需要同步的表編寫(xiě)三個(gè)觸發(fā)器,工作量巨大;

          (2)       觸發(fā)器具有不容易排錯(cuò)、可移植性差、占用資源大等缺點(diǎn);

          (3)       代碼可復(fù)用性不好。

          3.2.2 按系統(tǒng)操作同步

           按系統(tǒng)操作同步就是在所有進(jìn)行數(shù)據(jù)庫(kù)更新操作的地方都將其轉(zhuǎn)換成對(duì)方的數(shù)據(jù)庫(kù)操作進(jìn)行,例如在新系統(tǒng)進(jìn)行注冊(cè)操作(可能涉及到56個(gè)表進(jìn)行操作)時(shí),轉(zhuǎn)換為對(duì)方的注冊(cè)操作。

          這種同步方式的缺點(diǎn)在于:

          1)不通用:在每加一個(gè)系統(tǒng)操作或做一些小改動(dòng)時(shí),都需要對(duì)代碼進(jìn)行修改;

          2)代碼耦合度高:需要在所有操作的地方進(jìn)行處理,轉(zhuǎn)換成對(duì)方的SQL語(yǔ)句,代碼耦合度非常高;

          3)工作量很大:需要對(duì)所有兩邊的操作進(jìn)行一次手工“轉(zhuǎn)譯”操作,工作量很大。

          3.2.3 按數(shù)據(jù)庫(kù)表操作同步

           按表操作同步的“原子”是對(duì)單個(gè)表的的INSERT、UPDATEDELETE操作,它并不關(guān)注操作,例如:如果一個(gè)注冊(cè)操作對(duì)應(yīng)5個(gè)INSERT操作、2個(gè)UPDATE操作,它將其作為7個(gè)原子操作依次處理,并不對(duì)這些SQL進(jìn)行關(guān)聯(lián)。

          這種同步方式的優(yōu)點(diǎn)在于:

          1)相對(duì)比較通用:有一些比較簡(jiǎn)單的對(duì)應(yīng)關(guān)系的表,例如只是因?yàn)樽侄蚊Q、表名和字段個(gè)數(shù)等不同而需要進(jìn)行同步的表可交給“SQL語(yǔ)句解析器通用程序”進(jìn)行處理,對(duì)于某些復(fù)雜的表才需要進(jìn)行單獨(dú)編寫(xiě)業(yè)務(wù)來(lái)進(jìn)行轉(zhuǎn)換處理;

          2)代碼耦合度比較低:只需要捕獲對(duì)同步的表的INSERT、UPDATEDELETE操作的語(yǔ)句,基本不需要在代碼中加入對(duì)同步的處理。舊系統(tǒng)中不需要在上層進(jìn)行處理,在存儲(chǔ)過(guò)程中相關(guān)語(yǔ)句前處理同步即可。新系統(tǒng)只需要在同步接收進(jìn)程中指定需要處理的業(yè)務(wù)即可。

          推薦使用該同步方式。

          3.3 難點(diǎn)問(wèn)題

          3.3.1 自增主鍵

          當(dāng)表的主鍵為自增序列號(hào)時(shí),在插入時(shí)并不指定該字段的值,在某一方插入后,轉(zhuǎn)換為對(duì)方的SQL語(yǔ)句后,插入對(duì)方的數(shù)據(jù)庫(kù),很大可能兩邊的這條記錄的主鍵ID不一致。在根據(jù)自增序列號(hào)進(jìn)行這條記錄的updatedelete操作時(shí),因?yàn)閮蛇呁粭l記錄的id不一樣,很大可能導(dǎo)致刪除或更新的記錄并不是想要進(jìn)行刪除或更新的記錄。

          因此,在系統(tǒng)中盡量少用自增序列號(hào)主鍵,若能找到某幾個(gè)字段作為復(fù)合主鍵,可進(jìn)行修改,萬(wàn)一找不到,可采用字符類型的唯一標(biāo)識(shí)號(hào),例如:時(shí)間+自動(dòng)機(jī)號(hào)+若干位隨機(jī)數(shù)數(shù),在INSERT操作時(shí)指定該主鍵的值。

          不過(guò),一些只進(jìn)行INSERT操作的表,例如未接來(lái)電表采用自增序列號(hào)暫時(shí)也不用遇到什么問(wèn)題。在筆者所遇到的平臺(tái)中,新系統(tǒng)基本去除了自增主鍵,舊系統(tǒng)涉及自增主鍵的表并不太多,而且基本都能找到表中其它的2、3個(gè)字段作為唯一主鍵。

          3.3.2 事務(wù)問(wèn)題

          無(wú)法實(shí)現(xiàn)一些帶事務(wù)的操作。例如注冊(cè)等流程,因?yàn)椴捎冒凑諗?shù)據(jù)庫(kù)操作進(jìn)行同步,注冊(cè)操作被分解成多個(gè)原子操作,只能當(dāng)成單個(gè)多條SQL語(yǔ)句單獨(dú)進(jìn)行處理。

          需要事務(wù)的操作并不多,可將這些操作改成采用“按系統(tǒng)操作同步”,例如當(dāng)舊系統(tǒng)進(jìn)行注冊(cè)流程中,調(diào)用新系統(tǒng)提供的接口,由接口程序也進(jìn)行一個(gè)在新Oracle庫(kù)的注冊(cè)流程。

          3.3.3 定期數(shù)據(jù)校驗(yàn)

                   數(shù)據(jù)校驗(yàn)也是異構(gòu)數(shù)據(jù)庫(kù)的一個(gè)重要問(wèn)題,進(jìn)行一段時(shí)間的同步后,怎么能保證兩邊的數(shù)據(jù)庫(kù)是同步的?數(shù)據(jù)校驗(yàn)的周期如何,是一天,幾天,還是?

          進(jìn)行數(shù)據(jù)校驗(yàn)首先要確定校驗(yàn)指標(biāo),最簡(jiǎn)單的校驗(yàn)指標(biāo)是重要表的數(shù)據(jù)量是否相等,另外就是檢查表里面的數(shù)據(jù)是否一致,是否能保證能完成同樣的功能,可采用抽查機(jī)制等,這些工作不可能靠手工完成,因此需要提供數(shù)據(jù)校驗(yàn)的程序。數(shù)據(jù)校驗(yàn)的周期應(yīng)該是可配置的。

          3.3.4 日志記錄

          在進(jìn)行同步的過(guò)程中,有可能因?yàn)楦鞣N原因?qū)е罗D(zhuǎn)換為對(duì)方的數(shù)據(jù)庫(kù)語(yǔ)句后執(zhí)行失敗,為了日后進(jìn)行處理和分析,進(jìn)行錯(cuò)誤日志的記錄也是非常必要的。

          posted on 2011-07-23 22:37 阿蜜果 閱讀(3584) 評(píng)論(0)  編輯  收藏 所屬分類: 解決方案
          <2011年7月>
          262728293012
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

                生活將我們磨圓,是為了讓我們滾得更遠(yuǎn)——“圓”來(lái)如此。
                我的作品:
                玩轉(zhuǎn)Axure RP  (2015年12月出版)
                

                Power Designer系統(tǒng)分析與建模實(shí)戰(zhàn)  (2015年7月出版)
                
               Struts2+Hibernate3+Spring2   (2010年5月出版)
               

          留言簿(263)

          隨筆分類

          隨筆檔案

          文章分類

          相冊(cè)

          關(guān)注blog

          積分與排名

          • 積分 - 2296332
          • 排名 - 3

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 恭城| 偃师市| 沧源| 赤水市| 定陶县| 建水县| 墨江| 西乌珠穆沁旗| 梅河口市| 汾阳市| 石台县| 崇礼县| 钟山县| 象州县| 东港市| 达孜县| 桂平市| 临汾市| 页游| 古蔺县| 邹平县| 肥城市| 黄冈市| 新野县| 芦溪县| 广西| 喜德县| 东山县| 英吉沙县| 平罗县| 岳阳市| 陵水| 江阴市| 大理市| 虎林市| 福安市| 孟津县| 忻城县| 泾源县| 玉门市| 陈巴尔虎旗|