mysql或者tidb写数据出现主键冲突怎么办
2021-08-06 本文已影响0人
PENG先森_晓宇
什么是主键冲突
可以看到关键字Duplicate+entry
和for key PRIMARY
,大致意思就是主键重复录入
,出现这种错误提示就是主键冲突了。
err_info=Duplicate+entry+'sf111-2021-07-26+12:00:00'+for+key+'PRIMARY' optime=1628161424.4671 logid=162816142436391341 SFID= msg= from=/home/sftcwl/odp_sds/vendor/sftcwl/orm/src/DB.php:170 method=query req_start_time=1628161424.3696 write=0 is_submit=1 service=db/tidb_data/sds_data sql=INSERT+INTO+single_threshold_result+(area,+area_group,+dept_code,+loginid,+login_id,+order_aoi_type,+waybill_order_no,+execution_time)+VALUES+('太原',+'A',+'f444',+'777',+'32324',+'CBD',+'sf111',+'2021-07-26+12:00:00'),+('太原',+'A',+'f444',+'8888',+'32324',+'CBD',+'sf222',+'2021-07-26+12:00:00')
解决方式
先查询后写入
这种方式应该是大多数人首先想到的方式,先查询如果存在则不插入,不存在则插入。
缺点不言而喻,多一次查询mysql操作,如果插入数据量很大,该种方式很耗时间和性能,不推荐使用该方法。
使用on duplicate key update
该方式是在插入数据的时候如果报主键冲突,可更新已存在数据。
student表含俩条数据,id为主键,如下
- 单条插入更新
INSERT INTO student ( id, NAME, score )
VALUES
( 2, '小雨', 99 )
ON DUPLICATE KEY UPDATE NAME = '小雨'
执行完sql语句之后发现id为2的name修改为了小雨,并没有报主键冲突的问题。
- 批量插入更新
批量插入时,需要注意一个values()
函数,表示获取新插入的值。在批量数据插入时,通常插入的某条数据发生冲突时并不是直接将某个字段修改为某个固定的值,而是与插入的数据有关。
比如新插入数据如果发生冲突,那么将原有的name字段修改为现有数据的name值,此时values()
函数就派上用场了。
score=score+values(score)
这个表示原来的score的值+本次插入的数据score的值,这个也是很重要的。
insert into student(id,name,score) values
(2,'冰雹',10),
(3,'大雨',20),
(4,'春秋',70)
on duplicate key update name=values(name),score=score+values(score);
image.png
可以看到id为2和3的数据已经更新name和score字段,并且新增id为4的数据