綜合前面的幾個(gè)例子,我們這里來是實(shí)現(xiàn)下增量數(shù)據(jù)的同步。
這里只是分享一種方法,實(shí)際工作中,還會(huì)有其他更好的方案。
增量同步的整體思路一般就是:首先拿到這張表的增量數(shù)據(jù),怎么拿增量呢,源表需要有一個(gè)時(shí)間字段,代表該條記錄的最新更新時(shí)間(及只要該條記錄變化,該時(shí)間字段就會(huì)更新),當(dāng)然有時(shí)間字段最好了,沒有的話,可能需要做全表對比之類的操作;正常情況下,業(yè)務(wù)系統(tǒng)的表中都是有主鍵的,我們拿到增量數(shù)據(jù)之后,需要判斷該記錄的新插入的,還是更新的記錄,如果是更新記錄,我們需要先將數(shù)據(jù)加載到中間表,然后,根據(jù)主鍵將目標(biāo)表中已存在的數(shù)據(jù)刪除,最后再將本次的增量數(shù)據(jù)插入到目標(biāo)表。
1.配置表的設(shè)計(jì)(元數(shù)據(jù)表)
首先我們需要一張配置表,來保存我們要增量同步的表的基本信息
--元數(shù)據(jù)表
create table tm_etl_table(
table_name varchar(50), --表名
is_run int , --調(diào)度狀態(tài)
update_time timestamp,--表數(shù)據(jù)更新時(shí)間
etl_insert_time timestamp --記錄更新時(shí)間
);
我們初始化一條記錄,我們就以這張ods_tm_book表
一些基礎(chǔ)表準(zhǔn)備
-- 源表
create table tm_book(id int,book_name varchar(10),latest_time timestamp);
-- 源表數(shù)據(jù)初始化
insert into tm_book(id,book_name,latest_time)
select x,x||'_name',clock_timestamp() from generate_series(1,10) x;
-- 目標(biāo)表和中間表
create table ods_tm_book(id int,book_name varchar(10),latest_time timestamp,etl_insert_time timestamp);
create table staging_tm_book(id int,book_name varchar(10),latest_time timestamp);
源表中的數(shù)據(jù)
2.同步數(shù)據(jù)的流程開發(fā)
整體流程是這樣的,注意下,這個(gè)只是為了簡單演示了這個(gè)增量的例子,實(shí)際應(yīng)用的話得修改,這是有漏洞的。
2.1更新元數(shù)據(jù)表的狀態(tài)并獲取表更新時(shí)間
就是我們第一個(gè)狀態(tài),我們更新tm_etl_table表,更新is_run=0,表示我們開始同步數(shù)據(jù)了,update_time,初始化為 ‘1970-01-01’,表示我們要拉取所有的數(shù)據(jù)
這里,我們將該表的更新時(shí)間作為變量,我們會(huì)在后面的轉(zhuǎn)換中使用

2.2 加載數(shù)據(jù)到中間表
我們這里,直接表對表,將數(shù)據(jù)插入到staging
其中,表輸入中,我們需要根據(jù)前面的更新時(shí)間變量,獲取增量數(shù)據(jù),注意,需要勾選上“替換SQL語句中的變量”
這里,我們直接就表輸出到中間表,每次都需將清空表數(shù)據(jù)
2.3 加載數(shù)據(jù)到目標(biāo)表
這里,主要有3段腳本(為了方便,就這樣吧),根據(jù)主鍵ID,清空目標(biāo)表數(shù)據(jù),然后,將數(shù)據(jù)插入到目標(biāo)表,最后,更新tm_etl_table表中的記錄狀態(tài)
好了,用Kettle實(shí)現(xiàn)一個(gè)增量的邏輯大概就是這樣了,
3.小結(jié)
這里整理幾個(gè)問題
3.1 中間表
這里的話,使用了中間表,Kettle中是有一個(gè)控件的,應(yīng)該叫那個(gè)“插入/更新”,可以根據(jù)主鍵將數(shù)據(jù)更新掉,這個(gè)控件之前使用時(shí),發(fā)現(xiàn)很慢,就一直沒用,后面的話,可能會(huì)寫個(gè)例子,簡單測試看看。使用中間表,緩存下數(shù)據(jù),也是不錯(cuò)的方法。
3.2 增量流程
目前公司中,增量抽取,是這樣的,首先各個(gè)業(yè)務(wù)系統(tǒng)的數(shù)據(jù)導(dǎo)出到文本文件,然后批量將文件加載到數(shù)據(jù)倉庫中(這里使用循環(huán)加載的)。因?yàn)槊刻斓臄?shù)據(jù)量比較大,如果知己到表的話,會(huì)很慢,使用文件,一些數(shù)據(jù)庫都有批量加載的命令,很快很方便,比如:PostgreSQL中的copy命令,Greenplum中的外部表,還有Mysql中的load data等等。