生成唯一随机编码 并批量插入Mysql的一次业务实践(INSERT IGNORE)

in 普通BLOG
4274 评论 阅读量:398

程序需生成编码(唯一)作为外包装的打印喷码,随机且唯一;目前操作一键生成超过5000条时,脚本执行时间过长。
排查后发现代码如下(伪代码演示):

$num = 5000; // 需要生成数据数量
// 循环
for ($i = 0; $i < $num; $i++) {
    do {
        $sn = getSn(); // 生成随机码
        $rowCount = pdoCount('table_sn', array('sn' => $sn)); // 数据库查重
    } while ($rowCount);

    $insert_data... // 插入数据准备
    pdoInsert('table_sn', $insert_data); // 插入数据
}


处理屎山总是让人兴奋且有成就感。。。
第一反应的思路,已存在的sn可以先遍历出来,在脚本中筛除而不是通过mysql;考虑到会有同时操作业务的情况,多个线程并发执行会造成脏写、幻读。
最终的解决方案:table_sn表新增sn字段的唯一索引进行约束,利用mysql的INSERT IGNORE方式插入
最终实现代码如下(伪代码演示):

$num = 5000; // 待插入数量
while ($num) { // 循环
    $sn = getSn(); // 生成随机码

    $insert_data... // 插入数据准备
    pdoQuery('INSERT IGNORE table_sn ...'); // 忽略插入

    $hasInsert = pdoInsertid(); // 是否插入成功
    if ($hasInsert) {
        $num--;
    }
}

业务问题必然无最优解,这次的方案可能还会遇到死循环(id自增失败/字段格式填写错误/必填字段报错等原因无法插入),重复写入(生产部署后未添加唯一约束)等等,代码只有在迭代的时候最完美。

Comments are closed.