Kettle中通過觸發器方式實現數據 增量更新


在使用Kettle進行數據同步的時候, 共有

1.使用時間戳進行數據增量更新

2.使用數據庫日志進行數據增量更新

3.使用觸發器+快照表 進行數據增量更新

 

今天要介紹的是第3中方法。

 

實驗的思路是這樣的,在進行數據同步的時候,

源數據表為A表, A表要對 目標表(target table) B 表和C表進行數據的同步更新。

即A表中的對應字段發生變化之后,

 會通過觸發器將對應變化的字段在A表中的主鍵值寫入到一個臨時表temp中(該表作為快照表使用)。

快照表中只有兩個字段,一個是temp_id,是快照表的主鍵,另一個是 A_id,記錄的是在A表中發生變化的字段對應的主鍵的值。

temp( temp_id int primary key auto_increment , A_id int );

 

接下來,通過對快照表temp進行掃描,把在B表和C表中出現的與temp表中與A_id相匹配的字段,

從B,C兩個目標表中進行移除。

 

在接下來,讓A表作為源 讓B和C作為目標 對B,C做插入/更新操作;

這樣就實現了A表對B,C兩個表的更新,在后續的操作中可以使用SQL語句將 temp表, 以及觸發器進行 drop操作,以免其浪費內存資源。

 

在創建 trigger的時候,只要針對A表的 刪除、 更新操作進行創建trigger 即可。

下面來分析一下,對A表進行的不同操作的情況:

 

1.如果是向A表中插入一行數據: 沒有對應的觸發器,新插入A表的recorder 並沒有被記錄到temp 快照表中,

所以不會對B,C表中對應的字段進行移除操作。(不對 A 表的Insert 操作創建 trigger

可以避免 如果對 A表進行插入的 主鍵值 在 B, C表中 根本找不到,

這樣的話無法 根據temp 中記錄的 主鍵值 對B,C表中的字段進行移除 )

即便不建立觸發器,后續操作中仍舊會因為有 插入/更新的這個 step,對B 表 和 C表進行插入操作的。

 

2.如果是向A表刪除一行數據的話, 對應創建的觸發器會將 A表中被刪除的 主鍵 字段寫入到 temp這個快照表中去,

接下來,會依照temp表中的字段對B 表和 C 表中的記錄進行移除操作。

而在后續的插入更新操作中,A表中已經將該記錄進行移除了,所以沒有對應的記錄對B,C兩張表進行插入操作。

 

3. 如果對A表中的某一條記錄 進行 Update 更新操作的話 ,對應Update進行創建的觸發器會 把A表中被更新的記錄

所對應的主鍵值 寫入到快照表 temp中去,

接下來會根據temp表中的主鍵值,對表B 表 C 中的字段進行移除,

然后對B表 C表 依照 A表中的字段進行 插入更新操作。

 

插入更新操作是這樣的,

如果是主鍵值相等的話, 目標表對應字段 與 源表對應字段 不相同,

就會對目標表字段進行依照 源表進行更新,

如果是某條記錄的 主鍵值 在源表中出現,但是在目標表中沒有出現的話,

則對目標表進行相應的插入操作。(依照源表)

 

========================================================================

 

接下來,簡單介紹一下實驗數據:

首先,在Mysql中創建3個表, A B C 表,

對應的字段都是一樣的,對應的數據也都是一樣的(為了簡便......)。

 

接下來,在Kettle的Spoon中創建下面的流程:

 

Main

 

 

 

主流程中需要注意的是,在整個流程中,前段的prepare 和 后續 finish 只需要執行一次,

中間的syn是需要重復循環的,至少LZ是這樣設計的,這樣可以使得在循環的這段時期中,

若是A表中的相關字段發生變化的話,會實時地將變化同步到 B C兩個表中。

 

 

 

 

 

Main.prepare

在創建觸發器的時候需要注意一下,LZ在實驗的時候,

發現如果觸發器若想觸發 多條操作的時候,

是要寫

" DELIMITER + 分隔符號 "

begin

commands

end

分隔符號

但是,kettle目前的版本是不支持 delimiter的, 也就是寫上之后會報錯,

不寫上,若是執行多條命令語句 后面是必須要加 分號 ";" 來結尾的,

不加分號,也會報錯,

若加上之后,觸發器會默認為 到分號 觸發內容就會結束, 也是出錯的,

 

LZ的這個步驟之所以沒有出錯是因為,LZ創建的 觸發器只有一條觸發語句,所以沒有用到 delimiter。

如果您想寫多條 觸發語句的話,在delimiter這里要注意一下吧~

 

 

 

 Main.syn

 

 

 Main.syn.delete_B_C_records

 

Main.syn.A_insert_BandC

這里需要注意的是,在A_insert_into_C這個步驟的時候,對應的目標表中要選擇為c表。

 

而且,使用觸發器+快照表 進行數據增量更新 主要是通過 :先根據源表中變化(update delete)的記錄 對應刪除目標表中的字段,

然后再,將A表中變化的字段插入到目標表中; 所以整個過程不存在 使用源表 對 目標表進行更新 操作。所以"不執行任何更新" 要勾選 .

 

Main.finish

收尾工作,主要回收資源,調用Sql語句,執行刪除 快照表、觸發器工作。

 

接下來我們向A表中,

1.insert 一條記錄,

2.delete一條 同時存在於 A B C表中的記錄,

3.update 一條A表中的記錄。

4.然后對 A表中的 同一條 記錄 先 update 再 delete 它 看結果如何

5.(元數據) A表中還有上一次實驗被存入的,但是B C兩張表中所沒有的 記錄:

原A:

原B:

原C:

 

after prepare:

 

modify A :

 

 

執行上述的 1 2 3 4 操作后:

A:

                       

 

snapshot table temp :

對A表的 id=8 進行一次update 一次 delete,

這個temp表需要對A_id進行去除重復記錄操作,這也是為什么要在syn.delete_B_C_records中

去除重復記錄的原因。

 

為了將整個流程分解,我們來調用Main.syn.delete_B_C_record 這個transformation:

之后顯示的

 

B:

C:

 

 

接下來,使用A表對B,C兩表進行 插入/更新步驟 即 Main.syn.A_insert_BandC

 

B:    C:

 

這樣的話,不僅實現了更新,刪除,同步操作,而且同樣把A表中的原來的字段同步到B C兩張表中去了。

如果,不希望將A表中原有數據同步到B,C表中的話,可以通過字段選擇來實現。

 

當然在具體業務中的情況要比實驗內容復雜得多,這里僅提供簡單的思路,

如果有不恰當之處,敬請指正。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM