You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

跨数据库表数据同步遇主键冲突,求每5分钟迁移的解决方案

解决跨库表同步的主键冲突与定时迁移问题

先纠正一下你原来SQL里的小问题:你要把db2.table的数据同步到db1.table,所以插入目标应该是db1.table,之前的语句方向搞反啦。下面分两部分帮你解决问题:

一、主键冲突的两种处理方案

首先得明确你的业务需求:是用db2的行完全覆盖db1的同主键行,还是只更新对应字段?两种场景的SQL写法不同:

1. 主键重复时整行覆盖(推荐如果db2是权威数据源)

INSERT ... ON DUPLICATE KEY UPDATE语法,当主键field_id重复时,直接用db2的字段值替换db1的对应行:

USE db1;
INSERT INTO table (field_id, field1, field2)
SELECT field_id, field1, field2 FROM db2.table
ON DUPLICATE KEY UPDATE
  field1 = VALUES(field1),
  field2 = VALUES(field2);
-- 注:主键field_id不用更新,因为已经是重复值,写上也不影响

2. 主键重复时仅更新指定字段

如果db1里有些字段是本地维护的,不想被db2覆盖,就只同步需要更新的字段(比如只更field1和field2),写法和上面类似,只是明确指定更新的字段即可。

关键前提:db1.tabledb2.tablefield_id必须是主键或者唯一索引,否则ON DUPLICATE KEY UPDATE不会触发,还是会报主键冲突错误。

二、每5分钟自动迁移的实现方案

存储过程是可选方案,不是必须的,这里给你两种常用的实现方式:

1. 用MySQL事件调度器+存储过程

先把同步逻辑封装成存储过程,再用事件调度器定时调用:

-- 创建存储过程
DELIMITER //
CREATE PROCEDURE SyncDb2ToDb1()
BEGIN
  USE db1;
  INSERT INTO table (field_id, field1, field2)
  SELECT field_id, field1, field2 FROM db2.table
  ON DUPLICATE KEY UPDATE
    field1 = VALUES(field1),
    field2 = VALUES(field2);
END //
DELIMITER ;

-- 启用MySQL事件调度器(默认可能关闭)
SET GLOBAL event_scheduler = ON;

-- 创建每5分钟执行一次的事件
CREATE EVENT SyncTablesEvery5Min
ON SCHEDULE EVERY 5 MINUTE
STARTS CURRENT_TIMESTAMP
DO CALL SyncDb2ToDb1();

2. 直接用系统定时任务(无需存储过程)

如果不想用MySQL的事件,也可以直接用系统的定时任务来执行SQL脚本:

  • Linux/macOS:编辑crontab,添加定时任务(注意替换用户名、密码和SQL):
*/5 * * * * mysql -u your_username -p'your_password' -e "USE db1; INSERT INTO table (field_id, field1, field2) SELECT field_id, field1, field2 FROM db2.table ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2);"

安全提示:不要明文写密码,最好用~/.my.cnf配置文件存储账号密码,避免泄露。

  • Windows:用「任务计划程序」创建定时任务,执行mysql.exe并传入SQL命令。

额外优化建议

如果你的表数据量很大,每次同步全表会影响性能,可以考虑添加时间过滤条件(如果表有更新时间字段的话),比如只同步最近5分钟新增/修改的数据:

SELECT field_id, field1, field2 FROM db2.table WHERE update_time >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)

这样能大幅减少每次同步的数据量,提升效率。

内容的提问来源于stack exchange,提问作者warfy

火山引擎 最新活动