摘要:本文主要介紹如何在數據庫中完成覆蓋式數據導入的方法。
前言
衆所周知,數據庫中INSERT INTO語法是append方式的插入,而最近在處理一些客戶數據導入場景時,常常遇到須要覆蓋式導入的狀況,常見的覆蓋式導入主要有下面兩種:mysql
一、部分覆蓋:新老數據根據關鍵列值匹配,能匹配上則使用新數據覆蓋,匹配不上則直接插入。sql
二、徹底覆蓋:直接刪除全部老數據,插入新數據。數據庫
本文主要介紹如何在數據庫中完成覆蓋式數據導入的方法。app
部分覆蓋
業務場景
某業務天天給業務表中導入大數據進行分析,業務表中某列存在主鍵,當插入數據和已有數據存在主鍵衝突時,但願可以對該行數據使用新數據覆蓋或者說更新,而當新老數據userid不衝突的狀況下,直接將新數據插入到數據庫中。以將表src中的數據覆蓋式導入業務表des中爲例:性能
應用方案
方案一:使用DELETE+INSERT組合實現(UPDATE也能夠,請讀者思考)
--開啓事務 START TRANSACTION; --去除主鍵衝突數據 DELETE FROM des USING src WHERE EXISTS (SELECT 1 FROM des WHERE des.userid = src.userid); --導入新數據 INSERT INTO des SELECT * FROM src WHERE NOT EXISTS (SELECT 1 FROM des WHERE des.userid = src.userid); --事務提交 COMMIT;
方案優勢:使用最多見的使用DELETE和INSERT便可實現。大數據
方案缺點:一、分了DELETE和INSERT兩個步驟,易用性欠缺;二、藉助子查詢識重,DELETE/INSERT性能受查詢性能制約。url
方案二:使用MERGE INTO功能實現
MERGE INTO des USING src ON (des.userid = src.userid) WHEN MATCHED THEN UPDATE SET des.b = src.b WHEN NOT MATCHED THEN INSERT VALUES (src.userid,src.b);
方案優勢:MERGE INTO單SQL搞定,使用便捷,內部去重效率高。spa
方案缺點:須要數據庫產品支持MERGE INTO功能,當前Oracle、GaussDB(DWS)等數據庫已支持此功能,mysql的insert into on duplicate key也相似此功能。.net
徹底覆蓋
業務場景
某業務天天給業務表中導入必定時間區間的數據進行分析,分析只須要導入時間區間的去除,不須要以往歷史數據,這種狀況就須要使用到覆蓋式導入。code
應用方案
方案一:使用TRUNCATE+INSERT組合實現
--開啓事務 START TRANSACTION; --清除業務表數據 TRUNCATE des; --插入1月份數據 INSERT INTO des SELECT * FROM src WHERE time > '2020-01-01 00:00:00' AND time < '2020-02-01 00:00:00'; --提交事務 COMMIT;
方案優勢:簡單暴力,先清理在插入直接實現相似覆蓋寫功能。
方案缺點:TRUNCATE清理業務表des數據時對錶加8級鎖直到事務結束,在因數據量巨大而INSERT時間很長的狀況下,des表在很長時間內是不可訪問的狀態,業務表des相關的業務處於中斷狀態。
方案二:使用建立臨時表過渡的方式實現
--開啓事務 START TRANSACTION; --建立臨時表 CREATE TABLE temp(LIKE desc INCLUDING ALL); --數據先導入到臨時表中 INSERT INTO temp SELECT * FROM src WHERE TIME > '2020-01-01 00:00:00' AND TIME < '2020-02-01 00:00:00'; --導入完成後刪除業務表des DROP TABLE des; --修改臨時表名temp->des ALTER TABLE temp RENAME TO des; --提交事務 COMMIT;
方案優勢:相比方案一,在INSERT期間,業務表des能夠繼續被訪問(老數據),即事務提交前分析業務可繼續訪問老數據,事務提交後分析業務能夠訪問新導入的數據。
方案缺點:一、組合步驟較多,不易用;二、DROP TABLE操做會刪除表的依賴對象,例如視圖等,後面依賴對象的還原可能會比較複雜。
方案三:使用INSERT OVERWRITE功能
INSERT OVERWRITE INTO des SELECT * FROM src WHERE time > '2020-01-01 00:00:00' AND time < '2020-02-01 00:00:00';
方案優勢:單條SQL搞定,執行便捷,可以支持一鍵式切換業務查詢的新老數據,業務不中斷。
方案缺點:須要產品支持INSERT OVERWRITE功能,當前impala、GaussDB(DWS)等數據庫均已支持此功能。
總結
隨着大數據的場景愈來愈多,數據導入的場景也愈來愈豐富,除了本文介紹的覆蓋式數據導入,還有其餘諸如忽略衝突的INSERT IGNORE導入等等其餘的導入方式,這些導入場景能夠以使用基礎的INSERT、UPDATE、DELETE、TRUNCATE來組合實現,可是也一樣會對高級的一鍵SQL功能有直接訴求,後面有機會再繼續介紹。
本文分享自華爲雲社區《數據庫覆蓋式數據導入方法介紹》,原文做者:along_2020 。