当前位置: 首页 > news >正文

mysql插入记录时违反唯一索引的处理

如果表中定义了唯一索引,而我们插入记录要避免违反这个约束,该怎么弄?

最原始的办法,是先查找一下,确认不违反,才插入。现在都用ORM框架来操作数据库,搞不好还要分成两个步骤,调用2个方法才能完成。或者搞一个存储过程之类。这种方法繁琐不说,其实还不可靠。在并发的情况下,并不能保证完全不违反约束。

mysql提供了一些语句来处理这种情况。

1、使用 INSERT IGNORE 语句
2、使用 ON DUPLICATE KEY UPDATE 从句
3、使用 REPLACE 语句

假设我们有一个用户表,user_id是主键,则user_id具有唯一约束。

+---------+------------+-----------+
| user_id | first_name | last_name |
+---------+------------+-----------+
|     202 | Thor       | Odinson   |
|     204 | Loki       | Laufeyson |
+---------+------------+-----------+
2 rows in set (0.00 sec)

现在要新增一个用户

INSERT INTO users 
  (user_id, first_name, last_name) 
VALUES 
  (202, "Tony", "Smith");

由于user_id=202已存在,必然报错:

ERROR 1062 (23000): Duplicate entry '202' for key 'users.PRIMARY'

这时候可以采用以下三种方法之一来处理:

1、使用 INSERT IGNORE 语句

示例:

INSERT IGNORE INTO users 
  (user_id, first_name, last_name) 
VALUES 
  (202, "Tony", "Smith");

执行该语句,如果表中不存在user_id=202的记录,则记录插入,和普通的insert没有区别;但如果已经存在,mysql将不插入吗,同时抛出一个警告,但不会导致异常。

2、使用 ON DUPLICATE KEY UPDATE 从句

示例:

INSERT INTO users
  (user_id, first_name, last_name) 
VALUES 
  (202, "Tony", "Smith")
ON DUPLICATE KEY UPDATE
  first_name = "Tony",
  last_name = "Smith";

如果不存在冲突,顺利插入;否则用指定的值update冲突记录。

这个语句特别适合无则插入,有则更新的场景。以前我们总是喜欢自己写一些 insertOrUpdate之类的方法,来应付上述情况。办法是先update,看看受影响的记录数是否为0,0的话说明表里没这个记录,于是插入。

3、使用 REPLACE 语句

是ON DUPLICATE KEY UPDATE 从句的替代。但这个方法比较狠,简单粗暴。一旦存在冲突的情况,会先将表里现有记录删掉,然后再插入新的。

示例:

REPLACE INTO users
  (user_id, first_name, last_name) 
VALUES
  (202, "Tony", "Smith");

参考文章:
MySQL - How to insert a new row only if data do not exist

相关文章:

  • 创建型模式-工厂方法模式(二)
  • 面试的时候要注意的坑
  • 虹科案例 | 虹科HiveMQ助力实现百万辆汽车智能互联
  • Nginx基础篇-Nginx的WEB模块~连接状态
  • 营收、利润双增长,龙湖集团找到多元增长的答案?
  • YOLO系列之yolov1解读(1)
  • Softing IT Networks线上研讨会 | 9月 (下篇)
  • HBase原理深入
  • webpack5 之 基础构建打包
  • STM32使用寄存器点灯实验
  • 技术对接35
  • 金仓数据库 KingbaseES 插件参考手册 plsql_pldbgapi
  • 测试面试 | 某 BAT 大厂测试开发面试真题与重点解析
  • 2022鹏城杯
  • Kubernetes学习笔记-保障集群内节点和网络安全(3)限制pod使用安全相关的特性20220828
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • angular学习第一篇-----环境搭建
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Js基础知识(一) - 变量
  • Linux链接文件
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • ReactNativeweexDeviceOne对比
  • vuex 学习笔记 01
  • 机器学习 vs. 深度学习
  • 力扣(LeetCode)22
  • 前端知识点整理(待续)
  • 入门到放弃node系列之Hello Word篇
  • 小而合理的前端理论:rscss和rsjs
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • #{} 和 ${}区别
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (07)Hive——窗口函数详解
  • (1)Android开发优化---------UI优化
  • (定时器/计数器)中断系统(详解与使用)
  • (一)Thymeleaf用法——Thymeleaf简介
  • (一)基于IDEA的JAVA基础12
  • (一)为什么要选择C++
  • (转)项目管理杂谈-我所期望的新人
  • .a文件和.so文件
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • /run/containerd/containerd.sock connect: connection refused
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • [3300万人的聊天室] 作为产品的上游公司该如何?
  • [BZOJ 4598][Sdoi2016]模式字符串
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
  • [C++]运行时,如何确保一个对象是只读的
  • [hibernate]基本值类型映射之日期类型
  • [HTML]Web前端开发技术6(HTML5、CSS3、JavaScript )DIV与SPAN,盒模型,Overflow——喵喵画网页
  • [Java]深入剖析常见排序