【Java-MySQL】MySQL 批量插入,如何不插入重复数据?

问大家一个问题,在MySql批量插入的时候,你们如何避免插入重复的数据,下面给出几个方案:


在这里插入图片描述

🛠 一、最佳方案:ON DUPLICATE KEY UPDATE

适用场景:存在唯一索引/主键冲突时需更新其他字段(如时间戳、计数器)。
原理:冲突时执行更新操作,不冲突则正常插入。
示例

INSERT INTO user (id, name, age)  
VALUES (1, '张三', 25), (2, '李四', 30)  
ON DUPLICATE KEY UPDATE age = VALUES(age);

优势
✅ 精确处理唯一键冲突,其他错误仍会抛出(安全)。
✅ 支持批量操作,高效更新重复数据。


二、忽略重复:INSERT IGNORE

适用场景:仅需跳过重复记录,不更新其他字段。
示例

INSERT IGNORE INTO user (id, name)  
VALUES (1, '张三'), (2, '李四');

注意
⚠️ 会忽略所有错误(如数据类型错误),仅适合数据质量高的场景。


🔄 三、替换重复:REPLACE INTO

适用场景:需彻底覆盖重复记录(先删除再插入)。
示例

REPLACE INTO user (id, name)  
VALUES (1, '张三'), (2, '李四');

缺点
❌ 自增 ID 可能变化(因先删后插)。
❌ 触发 DELETE + INSERT 事件(可能影响触发器)。


🔍 四、条件插入:INSERT ... WHERE NOT EXISTS

适用场景:依赖非唯一键条件去重(如业务逻辑)。
示例

INSERT INTO user (name, role)  
SELECT '张三', 'admin' FROM DUAL  
WHERE NOT EXISTS (SELECT 1 FROM user WHERE name='张三' AND role='admin');

注意
⚠️ 性能较低(需子查询),大数据量避免使用。


📌 关键前提:创建唯一索引!

ALTER TABLE user ADD UNIQUE INDEX idx_unique_name (name);  -- 单字段唯一索引  
ALTER TABLE user ADD UNIQUE INDEX idx_name_role (name, role);  -- 联合唯一索引  

无唯一索引则所有方案失效!


💎 总结:如何选择?

方案适用场景是否推荐
ON DUPLICATE KEY UPDATE冲突时需更新字段⭐⭐⭐⭐⭐
INSERT IGNORE简单跳过重复(数据质量高)⭐⭐
REPLACE INTO需完全覆盖旧数据
WHERE NOT EXISTS非索引条件去重

💡 实际建议

  1. 首选 ON DUPLICATE KEY UPDATE(安全+灵活),尤其 MyBatis 等框架可轻松集成批量操作。
  2. 海量数据时,提前按唯一键分组,减少事务锁竞争。
  3. 禁止重复时,务必提前创建唯一索引!

所有方案源码示例,请详见官方文档👉 (https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值