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

MySQL 處理插入主鍵/唯一鍵衝突三大方案:IGNORE、REPLACE、ON DUPLICATE KEY UPDATE 深度解析

     編輯:MySQL 資料庫相關知識

批次寫入資料時,主鍵或唯一鍵衝突是常見挑戰。MySQL 提供三種語法層面的處理機制:INSERT IGNORE、REPLACE INTO、INSERT ... ON DUPLICATE KEY UPDATE。本文透過實測案例深度解析三者行為差異、適用場景與效能特徵。

測試環境準備

CREATE TABLE Tignore (ID INT NOT NULL PRIMARY KEY, NAME1 INT) DEFAULT CHARSET=utf8;
CREATE TABLE Treplace (ID INT NOT NULL PRIMARY KEY, NAME1 INT) DEFAULT CHARSET=utf8;
CREATE TABLE Tupdate (ID INT NOT NULL PRIMARY KEY, NAME1 INT UNIQUE KEY) DEFAULT CHARSET=utf8;

方案一:INSERT IGNORE — 忽略衝突行

INSERT IGNORE INTO Tignore VALUES (1,1), (1,2), (2,2);

行為:遇到主鍵/唯一鍵衝突,跳過該行,繼續處理後續行,不報錯。
結果:僅插入 (1,1)、(2,2),第二行 (1,2) 被忽略。
適用場景:日誌寫入、冪等導入、不關心衝突行內容。

方案二:REPLACE INTO — 刪除舊行再插入新行

REPLACE INTO Treplace VALUES (1,1), (1,2), (2,2);

行為:衝突時先 DELETE 舊行,再 INSERT 新行。
結果:最終表內資料為 (1,2), (2,2)。
影響行數:回傳 4 rows affected(1 insert + 1 delete + 1 insert + 1 insert)。
⚠️ 關鍵風險:

  • 觸發 DELETE + INSERT 觸發器
  • 自增 ID 可能改變(若主鍵非衝突欄位)
  • 外鍵關聯可能導致級聯刪除
  • 效能較差(雙重寫入)

適用場景:需以新資料完全覆蓋舊資料、且無外鍵依賴的簡單表。

方案三:ON DUPLICATE KEY UPDATE — 就地更新

INSERT INTO Tupdate VALUES (1,1), (1,2) ON DUPLICATE KEY UPDATE NAME1 = NAME1 + 1;
INSERT INTO Tupdate VALUES (1,1), (1,2) ON DUPLICATE KEY UPDATE NAME1 = VALUES(NAME1) + 1;

行為:衝突時執行 UPDATE,不刪除舊行,保留主鍵、自增 ID、外鍵關聯。
兩種寫法差異:

寫法等效邏輯結果 (NAME1 初始=1)
NAME1 = NAME1 + 1UPDATE SET NAME1 = NAME1 + 1 WHERE ID=12 (累加)
NAME1 = VALUES(NAME1) + 1UPDATE SET NAME1 = 2 + 1 WHERE ID=13 (基於新值計算)

進階:唯一鍵衝突但主鍵不衝突

INSERT INTO Tupdate VALUES (1,1), (2,1) ON DUPLICATE KEY UPDATE NAME1 = VALUES(ID) + 1;

關鍵行為:UPDATE 針對衝突的唯一鍵對應行(此例 NAME1=1 對應 ID=1),不會插入 ID=2 的新行。最終僅更新 ID=1 行的 NAME1。

三方案對比總結

特性INSERT IGNOREREPLACE INTOON DUPLICATE KEY UPDATE
衝突處理忽略/跳過刪舊插新就地更新
保留主鍵/自增ID是否(可能變)是
觸發器僅 INSERTDELETE + INSERTUPDATE
外鍵安全安全風險(級聯刪除)安全
效能最好較差良好
回傳影響行數實際插入行數刪除+插入總和1=新增, 2=更新

支援語法範圍

三者皆支援標準 INSERT 語法變體:

  • INSERT INTO ... VALUES (...)
  • INSERT INTO ... SET col=val, ...
  • INSERT INTO ... SELECT ...

最佳實務建議

  • 預設首選 ON DUPLICATE KEY UPDATE:語義清晰、效能佳、保留關聯完整性。
  • 大量導入不關心衝突:使用 INSERT IGNORE,配合 LOAD DATA INFILE ... IGNORE 效能最高。
  • 避免 REPLACE INTO:除非明確需要「完全替換」語義且評估過觸發器/外鍵影響。
  • 複合唯一索引:ON DUPLICATE KEY UPDATE 以「第一個衝突的唯一鍵」決定更新目標行,設計索引順序時需考慮此行為。

掌握三種衝突處理機制的語義邊界與效能特徵,能針對不同業務場景(日誌寫入、資料同步、冪等 API、統計累加)選擇最適當的寫入策略,避免資料不一致與效能陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved