首页 > 数据库 >MySQL插入数据重复时,数据已经存在,则更新或者忽略,不存在,则插入数据

MySQL插入数据重复时,数据已经存在,则更新或者忽略,不存在,则插入数据

时间:2024-12-18 09:57:05浏览次数:8  
标签:INSERT users age 插入 MySQL 数据 name

实现MySQL插入数据重复时更新,数据不存在时插入,只使用一条SQL语句的需求,可以通过以下几种方法来实现:

首页先创建一张表,开始测试

-- 创建一张users表,并把name设置为唯一索引。
CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name_key` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

# 插入一条数据,做测试数据
INSERT INTO `users` (`name`, `age`) VALUES ('刘备', 50);

1. INSERT ... ON DUPLICATE KEY UPDATE

使用条件:

  • 表中必须存在主键或者唯一索引,用于判断数据是否重复。
执行逻辑:

先执行插入,如果不存在,则插入成功;如果唯一索引已存在,则删除刚刚插入的数据,再去更新之前存在的那条记录。

-- 再次插入这个唯一索引存在的数据,如果存在则修改
INSERT INTO `users` (`name`, `age`)
VALUES
	( '刘备', 60 ) ON DUPLICATE KEY UPDATE `name` = '张飞', `age` = 30;

你会发现影响了两条数据(删除了SQL执行时新增的数据,并把原来的数据修改了)

  • 再次查看数据表,数据被修改了

  • 再去查看自增id

优点:

  • 灵活,可以只更新部分字段,而不是全行替换。
  • 插入和更新在一条 SQL 语句中完成,效率较高。

缺点:

  • 仅适用于存在主键或唯一索引的表。
  • 如果多个字段导致唯一索引冲突,需要提前设计索引结构。
  • 执行更新时,会有额外的开销。并且使用自增id时,会丢失一个id。

2. REPLACE INTO

使用条件:

  • 表中必须存在主键唯一索引,用于判断数据是否重复。
执行逻辑:

以唯一键判断数据是否存在。如果不存在,那么新增;如果存在,先删除原来的数据,再新增。

REPLACE INTO `users` (`name`, `age`)
VALUES ('张飞', '55');

你会发现影响了两条数据(删除了原来的数据,并插入了新数据)

  • 再次查看数据表,原来的数据没有了,新的数据id值不一样

优点:

  • 逻辑简单,直接替换整行数据。
  • 适合替换所有列的场景。

缺点:

  • 删除操作会触发外键约束、触发器等,可能导致额外开销。
  • 删除和重新插入会导致主键的id值变化。
  • 对于大表来说,性能不如 ON DUPLICATE KEY UPDATE 高效。

3. INSERT IGNORE

使用条件:

  • 不需要依赖主键或唯一索引来触发冲突行为(但是需要唯一索引来作为是否重复的判断条件)。
执行逻辑:

会先执行插入,如果数据不存在,则插入成功;如果存在,则不插入。由于使用了ignore,所以会忽略索引存在错误。

INSERT IGNORE INTO `users` (`name`, `age`)
VALUES ('张飞', 50);

你会发现没有修改任何数据(因为当前唯一索引的数据已存在)

  • 再次查看数据表,没有任何变化

优点:

  • 控制更灵活,可以通过条件进行精确的更新操作。
  • 不会触发删除操作,不会影响外键。

缺点:

  • 不能更新数据,要想更新数据,需要额外的处理。

4. INSERT IF NOT EXISTS

使用条件:

  • 不需要依赖主键或唯一索引来触发冲突行为。
执行逻辑:

执行insert前,会先判断条件是否满足。通过not exists判断,如果不存在,则插入;如果存在,则不插入。

注意:新增记录时,select 字段 from,表名称是dual,并不是当前表。如果是当前表,那么在新增记录时(表中没有该记录)会报错。因为第2行的select从当前表查询,已经有了该值。所以必须是dual,或者是其他表也可以。

INSERT INTO `users` ( `name`, `age` )
SELECT
    '张飞',
    50
FROM
    DUAL 
WHERE
    NOT EXISTS ( SELECT * FROM `users` WHERE `name` = '张飞' );

你会发现没有修改任何数据

  • 再次查看数据表,没有任何变化

优点:

  • 避免重复数据:通过 NOT EXISTS 过滤掉已存在的数据,保证数据的唯一性。不需要依赖唯一索引和主键
  • 简洁:将检查与插入操作合并在一条 SQL 语句中,避免写多条查询。

缺点:

  • 性能开销:对于大表,NOT EXISTS 的子查询可能性能较差,尤其是在没有索引的情况下。
  • 不适合并发高的场景:在高并发插入时,可能仍然出现重复数据(需要借助唯一索引等约束)。
  • 不能修改数据:修改数据时,依然需要额外处理。

最后:附上所有测试SQL语句

CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name_key` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `users` (`name`, `age`) VALUES ('刘备', 50);

INSERT INTO `users` (`name`, `age`)
VALUES
	( '刘备', 60 ) ON DUPLICATE KEY UPDATE `name` = '张飞', `age` = 30;
	
SHOW TABLE STATUS LIKE 'users';

REPLACE INTO  `users` (`name`, `age`)
VALUES ('张飞', 55);

INSERT IGNORE INTO `users` (`name`, `age`)
VALUES ('张飞', 50);

INSERT INTO `users` ( `name`, `age` ) SELECT
'张飞',
50 
FROM
DUAL 
WHERE
	NOT EXISTS ( SELECT * FROM `users` WHERE `name` = '张飞' );

推荐使用场景

  1. 使用 INSERT ... ON DUPLICATE KEY UPDATE
    • 当表有主键或唯一索引,并且只需要更新部分字段时,这是最好的选择。
  2. 使用 REPLACE INTO
    • 当你需要替换整行数据,并且能接受删除旧数据触发的影响时。
  3. 使用 INSERT IGNORE
    • 当你需要灵活控制插入时,且不需要更新数据,数据存在则忽略。
  4. 使用 INSERT IF NOT EXISTS
    • 当你需要灵活控制插入时,且不需要依赖任何唯一约束的索引。

结束语根据实际业务场景选择合适的方案,以平衡性能和数据操作的复杂性。
——如果有更好的方法,希望大家能留言告诉我一下,一起学习进步。

标签:INSERT,users,age,插入,MySQL,数据,name
From: https://blog.csdn.net/weixin_46029085/article/details/144550402

相关文章

  • T-SQL备份还原SQL Server的数据库
    完整备份与还原备份数据库到指定的位置---完整备份backupdatabaseTest1todisk='D:\backups\Test1.bak'使用备份文件还原数据库--设置单用户模式alterdatabaseTest1setsingle_userWITHROLLBACKIMMEDIATE--还原数据库restoredatabaseTest1fromdisk='D:\ba......
  • 机台设备数据管控新方案,实现数据驱动,智慧升级!
    机台设备数据管控是指对生产设备在运行过程中产生的各类数据进行全面、系统、有效的管理和控制,以确保数据的准确性、完整性、安全性和有效利用。 机台设备数据管控主要内容为数据收集,如实时采集机台的运行数据,包括产量、质量、故障、运行状态(如启动、停止、故障等状态信息)、生......
  • 【Python】【数据分析】深入探索 Python 数据可视化:Matplotlib 绘图库完整教程
    目录引言一、什么是Matplotlib?1.1Matplotlib的安装1.2Matplotlib的基本功能二、Matplotlib的基础绘图2.1绘制折线图2.2绘制柱状图2.3绘制散点图2.4绘制饼图三、高级功能与定制3.1设置图表样式3.2使用子图3.3保存图表四、Matplotlib流程图4.1Mermaid流......
  • MySQL中的视图(如果想知道MYSQL中有关视图的知识,那么只看这一篇就足够了!)
        前言:视图(View)是数据库中一种虚拟的表,它通过封装复杂的查询简化数据操作,帮助用户更方便地访问数据。视图不仅提升了查询效率,还增强了数据安全性和逻辑独立性。✨✨✨这里是秋刀鱼不做梦的BLOG✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客在......
  • java 插入排序,原理、算法分析、实现细节、优缺点以及一些实际应用场景
    更多资源推荐:http://sj.ysok.net/jydoraemon提取码:JYAM实用优质资源/教程公众号【纪元A梦】 ###插入排序的详细解析探讨插入排序,包括其工作原理、算法分析、实现细节、优缺点以及一些实际应用场景。####1.基本概念插入排序是一种简单的排序算法,其核心思想是将数组分为已排......
  • Windows ANSI API 是指 Windows 操作系统 提供的一组 应用程序编程接口 (API),它们使用
    WindowsANSIAPI是指Windows操作系统提供的一组应用程序编程接口(API),它们使用ANSI字符集来处理字符串和文本数据。ANSI字符集是较为老旧的字符编码标准,通常对应的是Windows-1252编码(又称Latin-1)。这些API主要用于与字符串和字符数据交互。1. WindowsANSI......
  • 全平台局域网(内网)数据传输工具 LoadSend
    前言不同系统的电脑、手机,文件传输有没有简单一点的方法?手机是iPhone,电脑是Windows,如何更快捷传输文件呢?我们最常用和用得最多的文件传输工具可能就是微信以及QQ了吧!其实,如果只是在局域网内,用微信这一类聊天工具来传输文件并不算特别合适,除了可能存在的文件大小限制,最大的问......
  • 指令遵循数据集IFEval介绍:中英双语
    IFEval数据集介绍:评估大语言模型指令遵循能力1.IFEval数据集提出的问题随着大语言模型(如GPT-4、PaLM2等)在自然语言任务中的广泛应用,模型的指令遵循能力(InstructionFollowing)成为一个重要评估指标。IFEval数据集旨在解决现有评估方法的局限性:人工评估耗时高、成本大......
  • 从上千份大厂面经呕心沥血整理:大厂高频手撕面试题(数据结构篇 ,Java实现亲试可跑)
    怎么判断两个链表是否相交?怎么优化?判断两个链表是否相交可以采用多种方法。一种方法是使用双指针。首先分别遍历两个链表,得到两个链表的长度。然后让长链表的指针先走两个链表长度差的步数。之后,同时移动两个链表的指针,每次比较两个指针是否指向相同的节点。如果指向相同......
  • 【数据】链表
    Python链表详解(csdn.net)【链表与数组】数组:数据支持动态进行扩容,向数组内添加数据时内存已满,则python会开辟更大的内存空间,然后将现有元素复制到新的内存块中,然后添加新元素。  扩容操作通常涉及内存分配和元素复制,这可能会导致性能下降,特别是在频繁进行插入和删除操作的......