on duplicate key update踩坑记录
出现问题
场景再现:产品过来说有个问题,需要看一下,具体问题是:课程里面的简介修改了没有生效,还是老的数据。我当时的回复是:这个逻辑已经半年没改过了,怎么会有问题呢,我去看一下。
分析原因
我去测试环境验证了一下,发现确实出现问题了,我觉得很神奇,之前好好的,代码也没有动过了,为啥会出现问题。我就开始一步一步的进行排查, 最后发现是那个表新增了一个字段,代码逻辑也支持了这个字段,按道理也不会有问题,最后跟踪到sql,发现用了on duplicate key update的写法,我就去看了一下表的唯一索引,发现新增的字段也加入到了唯一索引里面。最后发现新增的字段默认为NULL,所以导致唯一索引不生效了。
解决方案
对新增的字段默认值设置为空字符串。这样唯一索引生效了,就可以使用on duplicate key update语法了。
原理分析
on duplicate key update的作用是,如果表中存在unique或者primary key索引,那么当唯一索引字段的值存在的时候,会进行更新,如果不存在,那么进行插入,比如以下语句:
INSERT INTO t1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
其中a是唯一索引字段,那么他等同于
UPDATE t1 SET c=c+1 WHERE a=1;
有一点不同的是,使用这个方法id总是自增,但是update是不会导致id自增的。上面的insert语句中如果b也是唯一索引字段,那么等同于下面sql:
UPDATE t1 SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
如果a=1 or b=2 匹配了多条数据,那么只会更新一行。所以我们需要避免在多个唯一索引里面使用on duplicate key update语法。
mysql英文地址:https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
所以是因为唯一索引失效导致on duplicate key update语法失效。
也可以关注我的公众号:程序之声
关注公众号,领取更多资源。