qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          數(shù)據(jù)庫(kù)表記錄的一種同步方案

           涉及到多個(gè)數(shù)據(jù)庫(kù)之間的同步,由于某些原因(某些數(shù)據(jù)庫(kù)只需要表內(nèi)部分?jǐn)?shù)據(jù);數(shù)據(jù)庫(kù)類型目前為MySQL,但可能后期部分?jǐn)?shù)據(jù)庫(kù)采用Oracle),不能采用MySQL的主從同步機(jī)制。由于對(duì)同步的實(shí)時(shí)性要求不高,記錄個(gè)數(shù)也不是太多,另外做了一種簡(jiǎn)易的同步方案。
            一、 通過(guò)觸發(fā)器生成數(shù)據(jù)表版本號(hào)
            將數(shù)據(jù)表的每次更新時(shí)間記錄到另一張版本表中。
          drop table if exists Tab_Version_Tab;
          create table Tab_Version_Tab
          (
          Tab_Name            char(40)    not null,       #表名  #
          TrigVersion         int         null,       #觸發(fā)版本號(hào)#
          SourceVersion           int         null,       #源版本號(hào)#
          LocalVersion            int         null,       #本地版本號(hào)#
          constraint pk_Tab_Version_Tab primary key(Tab_Name)
          );
          delete from Tab_Version_Tab;
          insert into Tab_Version_Tab values("Demo1_Tab", 0, 0, 0);
            觸發(fā)器腳本如下:
          drop trigger if exists trig_insert_Demo1_Tab;
          delimiter |
          create trigger trig_insert_Demo1_Tab after insert on Demo_Tab
          for each row
          begin
          update Tab_Version_Tab set TrigVersion=UNIX_TIMESTAMP() where Tab_Name = 'Demo1_Tab';
          end;
          |
          delimiter ;
            同樣可以建立update,delete的觸發(fā)器。郁悶的是MySQL的觸發(fā)器只支持for each row,效率會(huì)較低。

           在實(shí)際應(yīng)用中,觸發(fā)器腳本是用LUA腳本生成的。
          local file_in = "d:\\sync_tables.sql"
          local file_out = "d:\\sync_trigs.sql"
          local tbl_prop = {}
          local fp = io.open(file_in, "r")
          if fp then
          while true do
          s1 = fp:read("*l")
          if not s1 then break end
          _,_,s2 = string.find(s1, "\"([%w%_]+)\"")
          if s2 then
          tbl_prop[s2] = 1
          end
          end
          end
          local sql_prep = [[
          drop trigger if exists trig_$OP_$TAB;
          delimiter |
          create trigger trig_$OP_$TAB after $OP on $TAB
          for each row
          begin
          update Tab_Version_Tab set TrigVersion=UNIX_TIMESTAMP() where Tab_Name = '$TAB';
          end;
          |
          delimiter ;
          ]]
          local tbl_rep = {"insert", "update", "delete"}
          local fp_out = io.open(file_out, "w")
          if fp_out then
          fp_out:write("use xopensdb\n")
          for k,v in pairs(tbl_prop) do
          fp_out:write("-- triggers of " .. k .. "\n")
          for k1,v1 in pairs(tbl_rep) do
          local sql_out = sql_prep
          sql_out = string.gsub( sql_out, "$TAB", k);
          sql_out = string.gsub( sql_out, "$OP", v1);
          fp_out:write(sql_out)
          fp_out:write("\n")
          end
          fp_out:write("\n")
          end
          end
            二、 維護(hù)表記錄一致
            從數(shù)據(jù)庫(kù)定時(shí)訪問(wèn)Tab_Version_Tab,檢查是否發(fā)生變化,如果發(fā)生變化,則將主數(shù)據(jù)庫(kù)的數(shù)據(jù)表按條件導(dǎo)入到從數(shù)據(jù)庫(kù)的臨時(shí)表中,然后比較臨時(shí)表和本地表的記錄是否相同:
            1. 比較兩者記錄個(gè)數(shù)是否相同
            2. 用natural join取出的記錄個(gè)數(shù)和本地表記錄是否相同
            SELECT COUNT(*) FROM table_local NATURAL JOIN table_tmp;
            如果不同,則清空本地表,從臨時(shí)表插入。
            MySQL無(wú)DBLINK,否則訪問(wèn)遠(yuǎn)端數(shù)據(jù)庫(kù)會(huì)簡(jiǎn)單些。

          posted on 2014-01-22 10:14 順其自然EVO 閱讀(349) 評(píng)論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫(kù)

          <2014年1月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 三原县| 子洲县| 拉孜县| 长岛县| 马关县| 台前县| 宁远县| 七台河市| 淳化县| 彰武县| 宜川县| 衡南县| 桐梓县| 个旧市| 新巴尔虎右旗| 齐齐哈尔市| 剑阁县| 阳山县| 上林县| 萍乡市| 嵊泗县| 逊克县| 苗栗县| 安宁市| 玉屏| 兴仁县| 柳河县| 永善县| 金湖县| 绵竹市| 巢湖市| 万山特区| 虞城县| 沙雅县| 来凤县| 甘泉县| 唐海县| 行唐县| 象州县| 梁平县| 黄龙县|