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 Innodb关键特性之插入缓冲(insert buffer)
Apr 08 MySQL
探究Mysql模糊查询是否区分大小写
Jun 11 MySQL
SQL实现LeetCode(180.连续的数字)
Aug 04 MySQL
MySQL令人大跌眼镜的隐式转换
Aug 23 MySQL
mysql 索引合并的使用
Aug 30 MySQL
一次MySQL启动导致的事故实战记录
Sep 15 MySQL
MySQL数据库中varchar类型的数字比较大小的方法
Nov 17 MySQL
mysql数据插入覆盖和时间戳的问题及解决
Mar 25 MySQL
MySQL Server层四个日志的实现
Mar 31 MySQL
详细聊一聊mysql的树形结构存储以及查询
Apr 05 MySQL
详解Mysql事务并发(脏读、不可重复读、幻读)
Apr 29 MySQL
mysql幻读详解实例以及解决办法
Jun 16 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
php下实现农历日历的代码
2007/03/07 PHP
php仿discuz分页效果代码
2008/10/02 PHP
php实现无限级分类实现代码(递归方法)
2011/01/01 PHP
PHP 第二节 数据类型之转换
2012/04/28 PHP
PHP把网页保存为word文件的三种方法
2014/04/01 PHP
ThinkPHP自动完成中使用函数与回调方法实例
2014/11/29 PHP
php实现HTML实体编号与非ASCII字符串相互转换类实例
2016/11/02 PHP
js和jquery中循环的退出和继续下一个循环
2014/09/03 Javascript
安装vue-cli报错 -4058 的解决方法
2017/10/19 Javascript
vue2.0与bootstrap3实现列表分页效果
2017/11/28 Javascript
浅谈webpack打包之后的文件过大的解决方法
2018/03/07 Javascript
Javascript查看大图功能代码实现
2020/05/07 Javascript
[02:23]DOTA2英雄基础教程 幻影长矛手
2013/12/09 DOTA
[33:23]Secret vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[01:16:37]【全国守擂赛】第三周决赛 Dark Knight vs. 一个弱队
2020/05/04 DOTA
django中的HTML控件及参数传递方法
2018/03/20 Python
Jupyter中直接显示Matplotlib的图形方法
2018/05/24 Python
python 集合 并集、交集 Series list set 转换的实例
2018/05/29 Python
Python中捕获键盘的方式详解
2019/03/28 Python
flask框架单元测试原理与用法实例分析
2019/07/23 Python
对python中的os.getpid()和os.fork()函数详解
2019/08/08 Python
打包PyQt5应用时的注意事项
2020/02/14 Python
推荐8款常用的Python GUI图形界面开发框架
2020/02/23 Python
Python使用tkinter制作在线翻译软件
2021/02/22 Python
英国女装网上商店:I Saw It First
2018/10/18 全球购物
美国最佳选择产品网站:Best Choice Products
2019/05/27 全球购物
美国第一大药店连锁机构:Walgreens(沃尔格林)
2019/10/10 全球购物
一个C/C++编程面试题
2013/11/10 面试题
大学本科毕业生的自我鉴定范文
2013/11/19 职场文书
舞蹈教育学专业自荐信
2014/06/15 职场文书
物理学专业求职信
2014/07/04 职场文书
转正申请报告格式
2015/05/15 职场文书
2019企业文化管理制度范本!
2019/08/06 职场文书
零基础学java之循环语句的使用
2022/04/10 Java/Android
Python 绘制多因子柱状图
2022/05/11 Python
鸿蒙3.0体验感怎么样? 鸿蒙3.0系统评测向
2022/08/14 数码科技