MySQL 防止重复插入数据

Posted by icoding168 on 2020-03-09 16:48:37

分类: MySQL  

我们经常会发现在浏览器提交表单后,表里面会有一些重复的数据,如何防止发生这种情况呢,有以下几种方法。

前端加控制

在前端页面加一些控制,用户点击了提交按钮后,按钮应该被 disabled 掉,防止用户多次快速重复点击按钮,造成重复请求。但是这个方法也不是万能的,因为还可能会出现用户在上次请求还没被处理完的情况下刷新页面,这样按钮又可以点击了。所以最保险的方式应该是由后端来做,当然前端提前过滤掉重复请求可以减轻后端服务的负担。

MySQL 语句使用 on duplicate

使用 INSERT … ON DUPLICATE KEY UPDATE,意思就是假如数据已经存在就执行 update 来更新已有的数据,例子:

INSERT INTO t1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(c);

MySQL 加唯一索引

在不允许发生重复的字段上加上唯一索引,如果重复插入数据,MySQL 会抛异常的。但是这种方法也是有局限性的,假如插入表的数据有两种情况,在第一种情况下不允许单个字段有重复,在第二种情况下又允许可以结合另一个字段来判断是否重复。这样的话,唯一索引就无法满足我们的需求了。因此,如果检测重复的规则比较复杂,那么建议不加唯一索引,而是在后端代码中加判断。

后端代码加判断

在后端代码中对检测重复的方法加锁,所有要执行写数据的请求都应该先调用这个方法。为什么要加锁呢 ?一般在后端代码做检测重复,都是先查询数据是否存在,再执行插入操作。这种读后写的操作对于 MySQL 来说并不是原子性的,可能会出现两个并发请求都在极短的时间差距内查询到数据不存在,然后都执行了后续的插入操作,导致重复数据的产生。

注意,假如对后端服务启用了负载均衡,也就是说有多个后端进程提供对外服务,那么应该使用分布式锁。