該方法適用場景:
表中有一列記錄該條字段最新修改時間的時間戳列。
核心思想:
用一張表記錄上次抽取的時間(初始時間2000-01-01),然後每次從源表接着上次的時間抽取數據到目標表。
一.前期準備
分表創建兩張表
# 創建源表
CREATE TABLE `im_message` (
`id` int NOT NULL AUTO_INCREMENT,
`sender` varchar(45) COLLATE utf8_bin NOT NULL COMMENT '消息發送者:SYSTEM',
`send_time` datetime(6) NOT NULL,
`receiver` varchar(45) COLLATE utf8_bin NOT NULL COMMENT '消息接受者',
`content` varchar(255) COLLATE utf8_bin NOT NULL COMMENT '消息內容',
`is_read` tinyint NOT NULL COMMENT '消息是否被讀取:0-未讀;非0-已讀',
`read_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='消息表'
;
# 創建目標表
CREATE TABLE `im_message_target` (
`id` int NOT NULL AUTO_INCREMENT,
`sender` varchar(45) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '消息發送者:SYSTEM',
`send_time` datetime(6) NOT NULL,
`receiver` varchar(45) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '消息接受者',
`content` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '消息內容',
`is_read` tinyint NOT NULL COMMENT '消息是否被讀取:0-未讀;非0-已讀',
`read_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='消息表'
;
# 創建存放時間戳的表
CREATE TABLE IF NOT EXISTS etl_temp(id int primary key,time_stamp datetime);
# 插入初始時間
INSERT INTO etl_temp (id,time_stamp) VALUES (1,'2000-01-01');
二.創建作業,拖入以下控件
三.創建<獲取上次執行時間>的轉換
表輸入中填入:
select date_format(time_stamp , '%Y-%m-%d %H:%i:%s') time_stamp
from etl_temp where id='1'
設置變量:
四.創建<增量同步>的轉換
原表輸入:
SELECT
id
, sender
, send_time
, receiver
, content
, is_read
, read_time
FROM im_message
where send_time>= date_sub(str_to_date('${TIME_STAMP}','%Y-%m-%d %H:%i:%s'), interval 1 day);
目標表輸入:
SELECT
id
, sender
, send_time
, receiver
, content
, is_read
, read_time
FROM im_message_target
where send_time>= date_sub(str_to_date('${TIME_STAMP}','%Y-%m-%d %H:%i:%s'), interval 1 day);
對比記錄:
對兩個表輸入查出的數據進行比對,並把比對的結果寫進輸入流,傳遞給後面的組件。
比對的結果(flagfield 標識字段)有三種:
- new
- changed
- deleted
標註字段表示比對結果的字段名,後面有用。關鍵字段表示比對的字段,在這個作業中我們比較兩個的主鍵ID
。
switch/case :
表輸出:
Kettle有一個插入/更新組件,但是據網友介紹這個組件性能低下,每秒最多隻能同步幾百條數據,所有我對插入和更新分別作了不同的處理。插入使用表輸出組件;更新使用更新組件。
爲了進一步提升同步效率,我在表輸出組件使用了多線程(右鍵>改變開始複製的數量),使同步速度達到每秒12000條。Switch組件和表輸出組件中間的虛擬組件(空操作)也是爲了使用多線程添加的。
更新:
刪除:
六.創建<更新時間戳>標識
update etl_temp
set time_stamp= (SELECT date_format(SEND_TIME , '%Y-%m-%d %H:%i:%s')
FROM im_message
ORDER BY SEND_TIME DESC LIMIT 1
)
where id='1';