mysql中数据库覆盖导入的几种方式总结


Posted in MySQL onMarch 25, 2022

众所周知,数据库中INSERT INTO语法是append方式的插入,而最近在处理一些客户数据导入场景时,经常遇到需要覆盖式导入的情况

常见的覆盖式导入主要有下面两种:

1、部分覆盖:新老数据根据关键列值匹配,能匹配上则使用新数据覆盖,匹配不上则直接插入。

2、完全覆盖:直接删除所有老数据,插入新数据。

mysql中数据库覆盖导入的几种方式总结

本文主要介绍如何在数据库中完成覆盖式数据导入的方法。

部分覆盖

业务场景

某业务每天给业务表中导入大数据进行分析,业务表中某列存在主键,当插入数据和已有数据存在主键冲突时,希望能够对该行数据使用新数据覆盖或者说更新,而当新老数据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即可实现。

方案缺点:1、分了DELETE和INSERT两个步骤,易用性欠缺;2、借助子查询识重,DELETE/INSERT性能受查询性能制约。

方案二:使用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搞定,使用便捷,内部去重效率高。

方案缺点:需要数据库产品支持MERGE INTO功能,当前Oracle、GaussDB(DWS)等数据库已支持此功能,mysql的insert into on duplicate key也类似此功能。

完全覆盖

业务场景

某业务每天给业务表中导入一定时间区间的数据进行分析,分析只需要导入时间区间的去除,不需要以往历史数据,这种情况就需要使用到覆盖式导入。

应用方案

方案一:使用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可以继续被访问(老数据),即事务提交前分析业务可继续访问老数据,事务提交后分析业务可以访问新导入的数据。

方案缺点:1、组合步骤较多,不易用;2、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功能有直接诉求,后面有机会再叙述。

MySQL 相关文章推荐
Mysql - 常用函数 每天积极向上
Apr 05 MySQL
MySQL InnoDB ReplicaSet(副本集)简单介绍
Apr 24 MySQL
仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案
May 06 MySQL
MySQL数字类型自增的坑
May 07 MySQL
MySQL 数据丢失排查案例
May 08 MySQL
解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
Jun 26 MySQL
MySQL Innodb索引机制详细介绍
Nov 23 MySQL
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
Feb 12 MySQL
MySQL七大JOIN的具体使用
Feb 28 MySQL
pt-archiver 主键自增
Apr 26 MySQL
MYSQL常用函数介绍
May 05 MySQL
mysql函数之截取字符串的实现
Aug 14 MySQL
Mysql如何实现不存在则插入,存在则更新
Mar 25 #MySQL
MySQL插入数据与查询数据
mysql insert 存在即不插入语法说明
Mar 25 #MySQL
MySQL创建表操作命令分享
mysql数据插入覆盖和时间戳的问题及解决
MySQL实战记录之如何快速定位慢SQL
Mar 23 #MySQL
MySQL中rank() over、dense_rank() over、row_number() over用法介绍
Mar 23 #MySQL
You might like
真正面向对象编程:PHP5.01发布
2006/10/09 PHP
php 使用fopen函数创建、打开文件详解及实例代码
2016/09/24 PHP
PHP封装的简单连接MongoDB类示例
2019/02/13 PHP
Laravel 在views中加载公共页面的实现代码
2019/10/22 PHP
JQuery中$.ajax()方法参数详解及应用
2013/12/12 Javascript
Javascript中封装window.open解决不兼容问题
2014/09/28 Javascript
浅谈Javascript变量作用域问题
2014/12/16 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
2015/03/09 Javascript
简介可以自动完成UI的AngularJS工具angular-smarty
2015/06/23 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
2016/06/12 Javascript
BootStrap Table 分页后重新搜索问题的解决办法
2016/08/08 Javascript
详解JS几种变量交换方式以及性能分析对比
2016/11/25 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
JS简单获取当前年月日星期的方法示例
2017/02/07 Javascript
js获取指定时间的前几秒
2017/04/05 Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
2017/08/28 jQuery
微信小程序利用button控制条件标签的变量问题
2020/03/15 Javascript
js实现弹窗猜数字游戏
2020/11/26 Javascript
详解Python3中的Sequence type的使用
2015/08/01 Python
你所不知道的Python奇技淫巧13招【实用】
2016/12/14 Python
PyCharm代码格式调整方法
2018/05/23 Python
Django学习笔记之为Model添加Action
2019/04/30 Python
python实现统计代码行数的小工具
2019/09/19 Python
在pytorch中对非叶节点的变量计算梯度实例
2020/01/10 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
英国领先的NHS批准的在线药店:Pharmacy2U
2017/01/06 全球购物
美体小铺英国官网:The Body Shop英国
2017/01/24 全球购物
英国汽车零件购物网站:GSF Car Parts
2019/05/23 全球购物
90后毕业生的求职信范文
2013/09/21 职场文书
《莫高窟》教学反思
2014/02/25 职场文书
美丽家庭事迹材料
2014/05/03 职场文书
2014国庆65周年领导讲话稿(3篇)
2014/09/21 职场文书
信访维稳工作汇报
2014/10/27 职场文书
经营目标责任书
2015/05/08 职场文书
2015年学校总务处工作总结
2015/05/19 职场文书
一劳永逸彻底解决pip install慢的办法
2021/05/24 Python