批量導入數據時,部分行主鍵或唯一鍵衝突,需按業務邏輯選擇:跳過、覆蓋、合併更新。
| 語法 | 行為 | 影響行數 | 適用場景 |
|---|---|---|---|
INSERT IGNORE | 衝突行靜默跳過,不報錯 | 成功插入行數 | 日誌去重、不關心衝突行 |
REPLACE INTO | 衝突先刪舊行再插新行 | 刪除+插入=2×衝突行數 | 全量覆蓋、自增 ID 會變 |
INSERT ... ON DUPLICATE KEY UPDATE | 衝突執行 UPDATE | 插入 1,更新 2 | 增量同步、計數器累加、字段合併 |
CREATE TABLE t (
id INT PRIMARY KEY,
val INT UNIQUE
) ENGINE=InnoDB;
INSERT IGNORE INTO t VALUES (1,10), (1,20), (2,30);
-- 結果:只插入 (1,10) 和 (2,30),(1,20) 靜默丟棄
REPLACE INTO t VALUES (1,10), (1,20), (2,30);
-- 過程:插入(1,10) → 衝突刪除(1,10)插入(1,20) → 插入(2,30)
-- 影響行數:4(2次插入+1次刪除+1次插入)
注意:自增主鍵會重新分配,外鍵關聯會斷裂。
-- 方式 A:引用表當前值
INSERT INTO t VALUES (1,10) ON DUPLICATE KEY UPDATE val = val + 1;
-- 相當於:INSERT ...; UPDATE t SET val = val + 1 WHERE id = 1;
-- 方式 B:引用插入值(VALUES() 函數)
INSERT INTO t VALUES (1,10) ON DUPLICATE KEY UPDATE val = VALUES(val) + 1;
-- 相當於:UPDATE t SET val = 10 + 1 WHERE id = 1;
-- 表結構:PRIMARY KEY(id), UNIQUE KEY uk_val(val)
INSERT INTO t VALUES (1,10), (2,10) ON DUPLICATE KEY UPDATE val = VALUES(id) + 1;
-- 唯一鍵 val=10 衝突,但主鍵 id=2 不衝突
-- 執行:UPDATE t SET val = 2+1 WHERE id = 1; -- 只更新第一行!
核心規則:UPDATE 的 WHERE 條件永遠是發生衝突的那個鍵對應的主鍵值,而非插入行的所有主鍵。
INSERT IGNOREREPLACEON DUPLICATE KEY UPDATE(首選)