当前位置:编程学习 > thinkphp >>

thinkphp 大批量插入数据提示 Duplicate entry for key PRIMARY

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'yizuotu.net' for key 'name' 
插入线程频率较高,没有处理好事务,造成插入sql执行顺序混乱
thinkphp5 模型多次save操作和insert,会产生重复的主键ID

thinkphp6 thinkphp8 甚至其他php也可以提示类似的错误的解决方法
在数据表导入的时候出现Duplicate entry ‘xxx’ for key ‘PRIMARY’错误
在thinkphp5.0.7版本下使用,如果用模型多次执行save操作,会提示产生的主键name重复。

原因:

建了主键的字段,重复数据反复插入

为什么会反复插入:例如有些特定环境,为了确保信息插入,同一条信息会提交N次


本来你的基本流程是:

1)先判断是否存在,不存在才插入


$name='yizuotu.net';
$ok = Db::name('yizuotu')->field("name")->where('name', $name)->find();

if ($ok){

echo "已经存在";

}else{

echo "不存在才插入:";

$p = Db::name('yizuotu')->insertGetId(['name'=>$name]);

if ($p){  
echo "成功插入";

}
}

2)而实际操作中,以上语句经常无效,根本没有过find(),就提示 重复数据,然后抛出错误

猜测:同一时间大量数据提交,mysql反应不过来


3)解决方法:

有条件写队列 redis,再慢慢出队列入库

捡便宜方法:INSERT IGNORE  忽略重复 或者 replace

Db::name('yizuotu')->replace()->insert(['name'=>$name]);


注意加:INSERT IGNORE 的话,找到文件:


thinkphp5增加过滤重复:
需更改框架文件:thinkphp\library\think\db\Query.php
$sql = str_replace('INSERT INTO', 'INSERT IGNORE INTO', $sql);


thinkphp6和thinkphp8过滤重复:

需更改框架文件:\vendor\topthink\think-orm\src\db\builder\Mysql.php
!empty($options['replace']) ? 'REPLACE' : 'INSERT',

直接改成  !empty($options['replace']) ? 'REPLACE' : 'INSERT IGNORE',


当然具体根据自己的需要调整

调整以后,相同主键的数据只插入1次,重复插入直接忽略

replace 就是用个最新的替换老数据

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,