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

Posted 左直拳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于mysql插入记录时违反唯一索引的处理的主要内容,如果未能解决你的问题,请参考以下文章

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

如何使用hibernate避免遇到违反唯一约束的问题?

MYSQL中的普通索引,主健,唯一,全文索引区别

mysql主键普通索引唯一索引和全文索引的比较

mysql主键普通索引唯一索引和全文索引的比较

mongodb 索引唯一性约束