• 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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    现在要新增一个用户

    INSERT INTO users 
      (user_id, first_name, last_name) 
    VALUES 
      (202, "Tony", "Smith");
    
    • 1
    • 2
    • 3
    • 4

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

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

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

    1、使用 INSERT IGNORE 语句

    示例:

    INSERT IGNORE INTO users 
      (user_id, first_name, last_name) 
    VALUES 
      (202, "Tony", "Smith");
    
    • 1
    • 2
    • 3
    • 4

    执行该语句,如果表中不存在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";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

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

    3、使用 REPLACE 语句

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

    示例:

    REPLACE INTO users
      (user_id, first_name, last_name) 
    VALUES
      (202, "Tony", "Smith");
    
    • 1
    • 2
    • 3
    • 4

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

  • 相关阅读:
    某森游戏列表
    Vue3实现获取验证码按钮倒计时效果
    d与C++的绑定的Calypso工具
    论文阅读——ELECTRA
    unity button移动位置some values driven by canvas
    2407. 最长递增子序列 II 线段树
    Vue中如何进行音视频录制与视频剪辑
    QT 6.5下载安装及配置教程
    springcloud使用openFeign
    react 实现chatGPT的打印机效果 兼容富文本,附git地址
  • 原文地址:https://blog.csdn.net/leftfist/article/details/126597656