MySQL合并存在ID冲突的两张数据表的解决方案咨询
ID冲突表合并通用解决方案
根据不同业务需求,可选择对应处理方案:
- 方案1:ID为无业务意义的自增主键,仅需做唯一标识
这种场景不需要保留table_B的原有ID,插入时跳过ID列让目标表自动生成新自增ID即可完全避免冲突,SQL示例(MySQL语法):INSERT INTO table_A (timestamp, price) SELECT timestamp, price FROM table_B; - 方案2:ID有业务意义,冲突时仅保留单表数据
如果你需要保留两张表的原有ID,仅在冲突时选择覆盖/跳过:- 冲突时保留table_A(本周数据),跳过table_B重复ID数据:
-- MySQL语法 INSERT INTO table_A (id, timestamp, price) SELECT id, timestamp, price FROM table_B ON DUPLICATE KEY UPDATE id=id; -- PostgreSQL语法 INSERT INTO table_A (id, timestamp, price) SELECT id, timestamp, price FROM table_B ON CONFLICT (id) DO NOTHING; - 冲突时覆盖table_A数据,保留table_B(上月数据):
INSERT INTO table_A (id, timestamp, price) SELECT id, timestamp, price FROM table_B ON DUPLICATE KEY UPDATE timestamp=VALUES(timestamp), price=VALUES(price);
- 冲突时保留table_A(本周数据),跳过table_B重复ID数据:
- 方案3:ID有业务意义,冲突时两张表数据都需要保留
给table_B的ID统一加偏移量,偏移量取table_A的最大ID值,保证B的ID不会和A重叠,同时保留B原有ID的相对关系:-- 先查询table_A的最大ID,示例中为5000,实际使用可替换为SELECT MAX(id) FROM table_A的结果 INSERT INTO table_A (id, timestamp, price) SELECT id + 5000, timestamp, price FROM table_B; - 方案4:需要区分数据来源,后续可按来源筛选查询
给table_A新增来源标识字段,将主键调整为「ID+来源」的复合主键,彻底解决冲突同时保留所有原始信息:-- 修改表结构,新增来源字段、调整主键 ALTER TABLE table_A ADD COLUMN source TINYINT NOT NULL DEFAULT 1 COMMENT '1=本周数据,2=上月数据', DROP PRIMARY KEY, ADD PRIMARY KEY (id, source); -- 插入table_B数据 INSERT INTO table_A (id, timestamp, price, source) SELECT id, timestamp, price, 2 FROM table_B;
内容的提问来源于stack exchange,提问作者Gustaf
相关产品推荐
相关产品推荐

