首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 處理重複鍵衝突的三種方案對比

     編輯:MySQL 資料庫相關知識

測試環境準備

CREATE TABLE test1(id INT PRIMARY KEY, name VARCHAR(5), type INT);
CREATE TABLE test2(id INT PRIMARY KEY, name VARCHAR(5), type INT);

INSERT INTO test1 VALUES (101,'aaa',1),(102,'bbb',2),(103,'ccc',3);
INSERT INTO test2 VALUES (201,'aaa',1),(202,'bbb',2),(203,'ccc',3),(101,'xxx',5);

方案對比表

語法衝突行為非衝突列處理適用場景
REPLACE INTO刪除舊行 → 插入新行未指定列置 NULL需完全覆蓋、主鍵/唯一鍵衝突
INSERT ... ON DUPLICATE KEY UPDATE更新指定列保留原值增量同步、計數器、部分更新
INSERT IGNORE忽略衝突,不插入保留原值冪等導入、去重、日志寫入

實戰演示

1. REPLACE INTO —— 全量覆蓋

-- 僅指定 id,name → type 變 NULL
REPLACE INTO test1(id,name) SELECT id,name FROM test2;
-- 結果:id=101 的 type 變 NULL

-- 全列指定 → 完整覆蓋
REPLACE INTO test1(id,name,type) SELECT id,name,type FROM test2;
-- 結果:id=101 變為 (101,'xxx',5)

2. INSERT ... ON DUPLICATE KEY UPDATE —— 精準更新

-- 僅同步 name,保留 test1 原有 type
INSERT INTO test1(id,name,type) SELECT id,name,type FROM test2
ON DUPLICATE KEY UPDATE test1.name = test2.name;

-- 結果:id=101 變為 (101,'xxx',1)  ← type 保持原值 1

3. INSERT IGNORE —— 靜默跳過

INSERT IGNORE INTO test1(id,name,type) SELECT id,name,type FROM test2;
-- 結果:id=101 保持 (101,'aaa',1) 不變,新 id 201~203 寫入

進階技巧與避坑

  • VALUES(col) 引用插入值:ON DUPLICATE KEY UPDATE cnt = cnt + VALUES(cnt)
  • REPLACE 觸發 DELETE + INSERT 觸發器,外鍵級聯需謹慎
  • IGNORE 會吞噬所有錯誤(不僅重複鍵),調試難,建議配合應用層檢查
  • 批量操作時,ON DUPLICATE KEY UPDATE 性能優於逐條 SELECT 判斷

選型決策樹

需要保留舊行其他列? → 是 → ON DUPLICATE KEY UPDATE
                               ↓ 否
允許靜默丟棄新數據? → 是 → INSERT IGNORE
                               ↓ 否
需完全用新數據覆蓋? → 是 → REPLACE INTO
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved