高级DBA教你达梦8国产数据库MergeInto批量插入并忽略主键重复报错特殊用法(达梦官方手册没有的内容)

news2024/11/23 1:18:25

高级DBA教你达梦8国产数据库MergeInto批量插入并忽略主键重复报错特殊用法(达梦官方手册没有的内容)

一、达梦8国产数据库简介

达梦 8 是一款由武汉达梦数据库有限公司基于 C/C++语言开发的国产关系型数据库,有支持 X86 和 ARM 平台的版本,可以部署到开源系统 CentOS6.X+及国产系统 KyLin-V4+上。作为国产关系型数据库,其 DM8 与 Oracle 数据库的设计思路非常相似。达梦数据库具有高性能、高可靠性和高安全性的特点,支持标准 SQL 语言,提供了丰富的数据库管理和查询功能,适用于各种规模和复杂度的企业应用。它可以运行在多种操作系统上,包括 Windows、Linux 和 UNIX 等。达梦数据库还提供了分布式数据库和集群技术,可以实现数据的高可用性和扩展性。它还支持数据备份和恢复、数据加密、权限管理等安全功能,保护数据的完整性和机密性。

达梦数据库在政府、金融、电信、制造等行业得到了广泛应用,具有较低的成本和良好的本地化支持,适合中国企业的需求。

达梦8(DM8)是武汉达梦数据库有限公司自主研发的新一代数据库管理系统,它是达梦数据库系列产品的最新版本之一,具有完全自主知识产权,是中国国产数据库领域中的重要产品。以下是达梦8数据库的一些核心特点和优势:

  1. 高性能与高可用性:DM8设计了全新的体系架构,旨在提升数据库处理大规模并发事务的能力,支持大规模并行计算和海量数据处理技术,适用于企业级应用,满足高吞吐量和低延迟的需求。同时,提供了多种高可用性解决方案,包括数据守护、读写分离等,保障业务连续性。

  2. 兼容性与易用性:DM8对Oracle SQL及过程化语言PL/SQL有良好的兼容性,这意味着对于熟悉Oracle的用户和开发者来说,转向DM8的学习曲线较低。此外,DM8提供了图形化的管理工具DM8Manager,界面友好,操作便捷,符合中国用户的使用习惯。

  3. 安全性与标准化:遵循国际和国内的多项安全标准,提供了全面的安全防护机制,包括数据加密、访问控制、审计追踪等功能,确保数据的安全性。同时,支持多种国家标准和行业规范,便于在不同领域的应用集成。

  4. 分布式与云计算支持:DM8融合了分布式和弹性计算技术,能够适配云计算环境,支持分布式部署,实现资源的弹性伸缩和负载均衡,满足云计算平台上的大数据处理需求。

  5. 智能化管理与运维:内置了智能化的诊断、优化和自我调优功能,能自动分析和解决数据库运行中遇到的问题,降低运维成本,提高效率。

  6. 广泛的应用场景:适用于政府、金融、电信、能源、制造等多个行业,支持OLTP(在线事务处理)、OLAP(在线分析处理)、数据仓库等多种应用场景。

达梦数据库作为国产数据库的代表之一,DM8在技术和市场上持续发展,致力于为用户提供稳定、可靠、高效的数据管理解决方案,推动国产数据库技术的进步与应用推广。

二、核心需求说明

笔者现在存在大数据条件,预计有几千万数据,我现在想批量插入表里面!
但是在插入过程中,遇到主键重复,导致一批数据插入失败了,我现在想解决一批数据插入过程中,如果遇到主键重复,忽略报错,继续插入呢!

数据库传统批量如下:

CREATE TABLE new_employees (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL,
    department VARCHAR(50),
    join_date DATE
);

INSERT INTO new_employees (emp_id, emp_name, department, join_date)
VALUES (1, 'Alice Lee', 'Marketing', '2023-01-01'), 
       (3, 'Charlie Brown', 'HR', '2024-03-01');

MyBatis 批处理用法

在 MyBatis 中,可以使用<foreach>标签来实现批量插入。以下是一个示例代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.swsmu.ebs.ebsbackend.ebsuser.mapper.TestMapper">
    <insert id="saveBatch">
        INSERT INTO product_test1 (
            `fund_code`,
            `fund_name`,
            `interview`,
            `deleted`,
            `born_date`
        ) VALUES
        <foreach collection="list" separator="," item="item">
            (#{item.fundCode},#{item.fundName},#{item.interview},0,#{item.bornDate})
        </foreach>
    </insert>
</mapper>

在上述代码中,saveBatch方法用于执行批量插入操作。<foreach>标签用于遍历集合中的每个元素,并将每个元素的值作为插入语句的参数。separator属性指定了元素之间的分隔符,在上述示例中,使用逗号作为分隔符。

在 Java 代码中,可以按照以下方式使用saveBatch方法:

List<FundProduct> list = new ArrayList<>();
list.add(new FundProduct("11", "Alice Lee", "Marketing", "2023-01-01"));
list.add(new FundProduct("3", "Charlie Brown", "HR", "2024-03-01"));

// 分片批量插入
List<List<FundProduct>> listPartition = Lists.partition(list, 500);
for (List<FundProduct> item : listPartition) {
    mapper.saveBatch(item);
}

在上述示例中,首先创建了一个包含要插入数据的列表list。然后,使用Lists.partition方法将列表分为多个子列表,每个子列表包含 500 个元素。最后,遍历每个子列表,并使用mapper.saveBatch方法将子列表中的数据批量插入到数据库中。

请注意,在实际应用中,可能需要根据具体的数据库配置和性能要求进行适当的调整。例如,可能需要考虑数据库的最大允许数据包大小、并发插入的数量等因素。

三、引入达梦数据库 MERGE INTO 解决

-- 创建临时表并插入数据
CREATE  TABLE employees (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL,
    department VARCHAR(50),
    join_date DATE
);

   drop table new_employees;
-- 创建临时表并插入数据
CREATE  TABLE new_employees (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL,
    department VARCHAR(50),
    join_date DATE
);

INSERT INTO new_employees (emp_id, emp_name, department, join_date)
VALUES (1, 'Alice Lee', 'Marketing', '2023-01-01'), 
       (3, 'Charlie Brown', 'HR', '2024-03-01');

-- 执行MERGE INTO操作
MERGE INTO employees e
USING new_employees ne
ON e.emp_id = ne.emp_id
WHEN MATCHED THEN
    UPDATE SET e.emp_name = ne.emp_name, e.department = ne.department, e.join_date = ne.join_date
WHEN NOT MATCHED THEN
    INSERT (emp_id, emp_name, department, join_date)
    VALUES (ne.emp_id, ne.emp_name, ne.department, ne.join_date);  
    

new_employees表数据插入employees表,过程中如果发现主键重复了,则更新!

传统批量插入语句如下:

INSERT INTO new_employees (emp_id, emp_name, department, join_date)
VALUES (1, 'Alice Lee', 'Marketing', '2023-01-01'),
(3, 'Charlie Brown', 'HR', '2024-03-01'); 

用达梦8 的MERGE INTO 批出来帮我写出来如下:

看起来可能存在一点混淆。实际上,MERGE INTO语句本身即用于实现根据匹配条件更新现有记录或插入新记录的目的,它已经支持批量处理多条数据。在之前的回答中,我已经提供了一个使用MERGE INTO来同时处理插入和更新的示例,其中包含了多条记录的操作。这里再次明确展示该批处理的MERGE INTO语句:

MERGE INTO employees e
USING (
    SELECT 1 AS emp_id, 'Alice Lee' AS emp_name, 'Marketing' AS department, '2023-01-01' AS join_date FROM DUAL
    UNION ALL
    SELECT 3, 'Charlie Brown', 'HR', '2024-03-01' FROM DUAL
) ne
ON e.emp_id = ne.emp_id
WHEN MATCHED THEN
    UPDATE SET e.emp_name = ne.emp_name, e.department = ne.department, e.join_date = ne.join_date
WHEN NOT MATCHED THEN
    INSERT (emp_id, emp_name, department, join_date)
    VALUES (ne.emp_id, ne.emp_name, ne.department, ne.join_date);

在这个例子中,我使用了一个子查询(联合了两个SELECT语句通过UNION ALL)来代替直接从new_employees临时表中选择数据,这样做是为了直接在MERGE INTO语句内部定义要处理的数据集,但这并不改变MERGE INTO批处理的本质。原本的临时表方法也是有效的,只要确保数据源(这里是new_employees)包含你想要合并的所有记录即可。

下面的执行例子也是笔者亲自执行过的!

drop table employees;
-- 创建临时表并插入数据
CREATE  TABLE employees (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL,
    department VARCHAR(50),
    join_date DATE
);
-- 下面是合并批量插入语句:反复执行插入同样的数据,最终结果只有2条,并且主键重发会触发更新!
  MERGE INTO employees e
USING (
    SELECT 1 AS emp_id, 'Alice Lee' AS emp_name, 'Marketing' AS department, '2023-01-01' AS join_date FROM dual
    UNION ALL
    SELECT 3, 'Charlie Brown', 'HR', '2024-03-01' FROM dual
) new_records
ON (e.emp_id = new_records.emp_id)
WHEN MATCHED THEN
    UPDATE SET e.emp_name = new_records.emp_name, e.department = new_records.department, e.join_date = new_records.join_date
WHEN NOT MATCHED THEN
    INSERT (emp_id, emp_name, department, join_date)
    VALUES (new_records.emp_id, new_records.emp_name, new_records.department, new_records.join_date); 

在这里插入图片描述
数据重复插入,反复执行,但是最终employees表中只存在2条,并且不会报错,也不会报主键重复,因为发现主键重复会触发更新操作!

mybatis的达梦8数据库的merge into 批量处理用法

在MyBatis中,你可以使用动态SQL标签来实现这样的迭代处理。通常,如果你有多个记录需要通过MERGE INTO语句处理,你会从一个集合中获取这些数据,然后在MyBatis映射文件中使用<foreach>标签来遍历这些记录。但是,直接将整个MERGE INTO语句作为动态SQL的一部分可能不太直观,因为MyBatis主要用于处理单行操作,而MERGE INTO是一个复合操作,涉及多行数据的逻辑处理。

一种可行的方法是将数据批量加载到数据库中后,单独执行一个MERGE INTO操作。不过,如果非要在MyBatis中模拟这种行为,可以通过构建动态的SQL片段来尝试接近这个目标。请注意,以下示例是概念性的,实际应用中可能需要根据具体需求调整,并且需要注意SQL注入风险和性能问题。

首先,假设你有一个Java实体类Employee,并且你的Mapper接口有一个方法接收List<Employee>类型参数。

Java Mapper Interface

public interface EmployeeMapper {
    @Insert("<script>" +
            "MERGE INTO employees e " +
            "USING (" +
            "<foreach item='item' collection='employees' separator=' UNION ALL '> " +
            "SELECT #{item.empId} AS emp_id, #{item.empName} AS emp_name, #{item.department} AS department, #{item.joinDate} AS join_date FROM dual " +
            "</foreach> " +
            ") new_records " +
            "ON (e.emp_id = new_records.emp_id) " +
            "WHEN MATCHED THEN " +
            "UPDATE SET e.emp_name = new_records.emp_name, e.department = new_records.department, e.join_date = new_records.join_date " +
            "WHEN NOT MATCHED THEN " +
            "INSERT (emp_id, emp_name, department, join_date) " +
            "VALUES (new_records.emp_id, new_records.emp_name, new_records.department, new_records.join_date)" +
            "</script>")
    void mergeEmployees(@Param("employees") List<Employee> employees);
}

注意事项

  1. 安全性与性能:这种方式虽然实现了动态生成MERGE INTO语句,但是可能对数据库性能产生较大影响,特别是当传入的集合非常大时。实际应用中应考虑分批处理或直接使用数据库的批量操作能力。

  2. SQL注入:MyBatis会自动处理参数绑定以防止SQL注入,但构建动态SQL时仍需小心处理。

  3. 数据库兼容性:请确保所使用的数据库(达梦8)支持MERGE INTO语法,并且MyBatis配置正确以适应特定的数据库方言。

  4. 测试:由于这种方法较为特殊,强烈建议在实际部署前进行充分的测试,以验证其正确性和性能表现。

四、笔者简介

国内某一线知名软件公司企业认证在职员工:任JAVA高级研发工程师,大数据领域专家,数据库领域专家兼任高级DBA!10年软件开发经验!现任国内某大型软件公司大数据研发工程师、MySQL数据库DBA,软件架构师。直接参与设计国家级亿级别大数据项目!并维护真实企业级生产数据库300余个!紧急处理数据库生产事故上百起,挽回数据丢失所造成的灾难损失不计其数!并为某国家级大数据系统的技术方案(国家知识产权局颁布)专利权的第一专利发明人!

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1648296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】 顺序表专题

目录 1.顺序表的概念及结构 1.1线性表 1.2顺序表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 1.顺序表的概念及结构 1.1线性表 线性表&#xff08;Linear List&#xff09;是数据结构中的一种基本结构&#xff0c;它是一个具有n个数据元素的有限序列。线性表的特点是数…

triton之fused attention

附录 【BBuf的CUDA笔记】十五,OpenAI Triton入门笔记三 FusedAttention - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/684557290图解大模型计算加速系列:FlashAttention V1,从硬件到计算逻辑 - 知乎 (zhihu.com)

MongoDB(四):条件操作符

条件操作 1、概述2、比较操作2.1、大于操作符-$gt2.2、大于等于操作符-$gte2.3、小于——$lt2.4、小于等于——$lte2.5、范围查询 3、总结 大家好&#xff0c;我是欧阳方超&#xff0c;可以扫描下方二维码关注我的公众号“欧阳方超”&#xff0c;后续内容将在公众号首发。 1、…

架构师:搭建Spring Security、OAuth2和JWT 的安全认证框架

1、简述 Spring Security 是 Spring 生态系统中的一个强大的安全框架,用于实现身份验证和授权。结合 OAuth2 和 JWT 技术,可以构建一个安全可靠的认证体系,本文将介绍如何在 Spring Boot 中配置并使用这三种技术实现安全认证,并分析它们的优点。 2、Spring Security Spri…

国产开源数据库厂商介绍

前言 开源数据库即免费的社区数据库,其源代码可供公众使用,并且可以在其原始设计中进行修改或使用。开源数据库的流行示例包括MySQL,PostgreSQL和MongoDB。开源数据库用户托管数据库部署的方式有内部部署、公共云、混合云。3. 互联网背景下,市场向互联网、移动化、数字化新…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-14-主频和时钟配置

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

深入 YOLOv8:探索 block.py 中的模块,逐行代码分析(一)

深入 YOLOv8&#xff1a;探索 block.py 中的构建块 YOLOv8&#xff0c;作为最新和最先进的对象检测模型之一&#xff0c;其核心架构由多个精心设计的构建块组成。这些构建块在 block.py 文件中定义&#xff0c;它们共同构成了 YOLOv8 的骨架。在本文中&#xff0c;我们将深入探…

【Java EE】多线程(三)线程状态

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…

面试笔记——垃圾回收

对象被垃圾回收的时机 垃圾回收主要面向的是堆中的对象。简单一句就是&#xff1a;如果一个或多个对象没有任何的引用指向它了&#xff0c;那么这个对象现在就是垃圾&#xff0c;如果定位了垃圾&#xff0c;则有可能会被垃圾回收器回收。 如果要定位什么是垃圾&#xff0c;有两…

做题速度太慢了,面不上

没办法&#xff0c;之前练了一个月的sql。两个月不写&#xff0c;现在差不多忘干净了。工作空窗期&#xff0c;或者休息期不能太久&#xff0c;不然学再多的内容都可能会忘完的。 sql题&#xff0c;腾讯四道sql题&#xff0c;限时45分钟完成。我只做了一道&#xff0c;还没做完…

自动控制原理MATLAB:控制系统模型构建

在MATLAB中&#xff0c;常用的系统建模方法有传递函数模型、零极点模型以及状态空间模型等。 1系统传递函数模型描述&#xff1a; 命令格式&#xff1a; systf(num,den,Ts); 其中&#xff0c;num、den为分子多项式降幂排列的系数向量,Ts表示采样时间&#xff0c;缺省时描述…

ppp和ppp mp理论实验

ppp简介 PPP&#xff08;点对点协议&#xff09;为在点对点连接上传输多协议数据包提供了一个标准方法&#xff0c;是数据链路层封装协议的一种方法&#xff0c;支持同步和异步两种传输方式。&#xff08;除了PPP还有HDLC等&#xff0c;不过HDLC只支持同步方式&#xff09; P…

语音识别之衡量声音之间的距离-理解DTW

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

2024年学浪课程提取工具blog

2024年&#xff0c;如果你还在为提取学浪课程而烦恼&#xff0c;快来了解我们全新推出的学浪课程提取工具&#xff01;这是一款高效实用的工具&#xff0c;能一键提取并保存课程视频、音频和文档&#xff0c;让学习变得更加轻松愉快&#xff01;从此告别繁琐的下载和整理过程&a…

Tensor Cores 解密:解锁深度学习新篇章

Tensor Cores 使用介绍 概要介绍 TensorCore是英伟达GPU自Volta架构起支持的特性&#xff0c;允许CUDA开发者利用混合精度来显著提升吞吐量&#xff0c;且不影响精度。TensorCore在Tensorflow、PyTorch、MXNet和Caffe2等深度学习框架中得到广泛支持&#xff0c;用于深度学习训…

VBA在Excel中注册登录界面的应用

Excel工作表也可以做一个小程序,登录注册后可以访问或修改。为了简便,没有做复杂的控件,能说明问题就行。可以根据需要添加更多的判断条件,控制注册和访问人数。本次操作对注册没有任何限制,只要注册后就可以根据注册的账号和密码进行访问和修改。注册登录界面截图: 操作…

Anatomical-Aware Point-Voxel Network for Couinaud Segmentation in Liver CT

文章目录 Anatomical-Aware Point-Voxel Network for Couinaud Segmentation in Liver CT摘要方法实验结果 Anatomical-Aware Point-Voxel Network for Couinaud Segmentation in Liver CT 摘要 在 CT 成像中&#xff0c;将肝脏准确分割为解剖片段对于手术规划和病变监测至关…

web前端学习笔记7-iconfont使用

7. iconfont的使用流程 字体图标使用较多的是阿里巴巴iconfont图标库,它是阿里巴巴体验团队推出的图标库和图标管理平台,提供了大量免费和可定制的矢量图标,以满足网页设计、平面设计、UI设计、应用程序开发和其他创意项目的需求。 官方网站:https://www.iconfont.cn/ 使用…

【Git管理工具】使用Docker+浪浪云服务器部署GitLab服务器

一、什么是GitLab 1.1.GitLab简介 GitLab 是一个开源的 DevOps 平台&#xff0c;它基于 Git 版本控制系统提供了从项目规划、源代码管理到持续集成、持续部署、监控和安全的完整生命周期管理。GitLab 是一个为开发者提供协作工作的工具&#xff0c;它使得团队能够高效地在同一…

海洋行业工业气体检测传感器的重要性

海洋行业是一个广阔而复杂的领域&#xff0c;涉及多个分支和应用&#xff0c;包括浮式生产、储存和卸载&#xff08;FPSO&#xff09;装置、渡轮和潜艇等。这些船舶和设施在执行任务时&#xff0c;都可能遇到各种潜在的气体危害。因此&#xff0c;对于海洋行业来说&#xff0c;…