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

作者:luckyone906 时间:2024-01-19 22:26:33 

众所周知,数据库中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)等数据库均已支持此功能。

来源:https://blog.csdn.net/u011555996/article/details/115641084

标签:mysql,数据库,覆盖,导入
0
投稿

猜你喜欢

  • python数据分析之聚类分析(cluster analysis)

    2022-12-28 08:24:02
  • Python 如何调试程序崩溃错误

    2022-04-27 15:22:30
  • 如何基于Python代码实现高精度免费OCR工具

    2022-10-17 07:53:47
  • Python和Sublime整合过程图示

    2023-04-11 15:23:33
  • MySQL学习笔记5:修改表(alter table)

    2024-01-23 23:01:16
  • django模板结构优化的方法

    2023-11-12 11:57:02
  • 浅谈五大Python Web框架

    2023-12-10 07:33:25
  • python中re.findall函数实例用法

    2021-03-28 07:51:20
  • 解决pytorch读取自制数据集出现过的问题

    2023-04-23 15:15:43
  • mysql中explain用法详解

    2024-01-13 16:28:25
  • 在python下实现word2vec词向量训练与加载实例

    2022-06-12 23:49:05
  • PyCharm上安装Package的实现(以pandas为例)

    2021-09-21 12:26:30
  • Python实现的概率分布运算操作示例

    2023-02-21 10:16:18
  • 将滚动条(scrollbar)保持在最底部的方法

    2008-02-21 10:05:00
  • Python全栈之列表数据类型详解

    2023-05-05 15:27:10
  • 基于Opencv的图像卡通化实现代码

    2023-07-10 06:58:55
  • django中模板的html自动转意方法

    2023-06-28 15:33:49
  • MySQL Index Condition Pushdown(ICP)性能优化方法实例

    2024-01-19 20:08:25
  • Python列表元素常见操作简单示例

    2022-08-18 08:33:57
  • Python asyncore socket客户端开发基本使用教程

    2021-01-25 11:06:39
  • asp之家 网络编程 m.aspxhome.com