業務常見「存在則更新、不存在則插入」需求,Hibernate 提供 saveOrUpdate,原生 SQL 有三種標準寫法。本文詳細對比 INSERT IGNORE、INSERT ... ON DUPLICATE KEY UPDATE、REPLACE INTO 的語法、語義差異、觸發器行為、主鍵/唯一鍵要求、性能特徵與適用場景。
INSERT IGNORE INTO tbl_name (col1, col2) VALUES (val1, val2);
INSERT INTO tbl_name (pk, col1, col2) VALUES (1, 'a', 'b')
ON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2);
BEFORE INSERT、BEFORE UPDATE、AFTER INSERT、AFTER UPDATE(視執行路徑)。REPLACE INTO tbl_name (pk, col1, col2) VALUES (1, 'a', 'b');
| 維度 | INSERT IGNORE | ON DUPLICATE KEY UPDATE | REPLACE INTO |
|---|---|---|---|
| 衝突動作 | 忽略 | 更新 | 刪除+插入 |
| 返回行數 | 0/1 | 1(新增)/2(更新) | 1(刪除)+1(插入)=2 |
| 自增 ID | 不變 | 不變 | 變更 |
| 觸發器 | 僅 INSERT 類 | INSERT/UPDATE 類 | DELETE+INSERT 類 |
| 隱藏錯誤 | 是(危險) | 否 | 否 |
| 推薦場景 | 冪等去重導入 | 業務 UPSERT(首選) | 極特殊替換需求 |
ON DUPLICATE KEY UPDATE,語義清晰、不隱藏錯誤、自增 ID 穩定。INSERT IGNORE,但必須配合嚴格的數據校驗流程。REPLACE INTO,除非經架構評審確認無外鍵、無觸發器、自增 ID 不被引用。ON DUPLICATE KEY UPDATE 會匹配任一唯一鍵衝突,確保業務邏輯與索引設計一致。