多套程序往同一 MYSQL 中插入

场景#

多套拉取 API 的程序,分别放在多台独立服务器中定时执行。由于所有程序链接的是同一个 MYSQL,写入时会有很条插入失败,因为 MYSQL 中设置了唯一字段对应 API 中的 ID

想法#

新增一个字段,如果数据不存在就插入一条新的,如果存在就把此字段 +1,但这样就意味着插入前就必须要先 select 一下是否存在,请问有没有比较好的方法?

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

用 mysql 的 INSERT INTO xxx ON DUPLICATE KEY UPDATE 方法, 这个是条件必须是一个唯一索引,如果不存在就插入,存在就更新。 但是这个方法的唯一缺点就是特别浪费自增 ID,相当于每操作一次都会自增 + 1? 这个 laravel 中也支持,好像是 upsert 这个方法吧。你可以试试。。

2年前 评论
畅畅 (楼主) 2年前
讨论数量: 15

建议全都插临时表,然后由多个消费程序来做

不要查,直接 update

两个方案

2年前 评论

可以考虑用 redis 的 setnx 实现。或者搞个本地文件锁也可以。只要不能拿到,那就表示别的进程在处理了。

2年前 评论

核心还是在于锁,或者原子性,也可以借助布隆过滤器在插入前过滤,

2年前 评论

要解决什么问题呢,或者预想的结果是什么

2年前 评论

去搜下 replace into,我猜你要的就是这个。

2年前 评论

用 mysql 的 INSERT INTO xxx ON DUPLICATE KEY UPDATE 方法, 这个是条件必须是一个唯一索引,如果不存在就插入,存在就更新。 但是这个方法的唯一缺点就是特别浪费自增 ID,相当于每操作一次都会自增 + 1? 这个 laravel 中也支持,好像是 upsert 这个方法吧。你可以试试。。

2年前 评论
畅畅 (楼主) 2年前

replace into 是正解

2年前 评论

INSERT INTO xxx ON DUPLICATE KEY UPDATEREPLACE INTO 产生死锁的概率较高,慎用

2年前 评论
mengdodo

把自增 id 的动作放在 redis 中,每次 insert 前先到 redis 中做 incr 动作,会返回给你自增后的 id,带着 id 再执行 insert

2年前 评论

正常不应该就依赖 MySQL 的自增 ID 么... 难道插入的时候要指定 ID?

2年前 评论

sql 语句可以解决,mysql 是很强的的

2年前 评论

laravel 有个方法是 updateOrCreate 思路虽然也是先查询再更新 但是用这个方法便捷一些

2年前 评论