數(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ù)