掌握這三種進階插入模式,靈活應對資料遷移、去重、Upsert 等常見業務場景。
場景:表 B 滿足條件的資料複製到表 A。
-- 表 A(id, cola) 表 B(id, cola, colb...)
INSERT INTO A (id, cola)
SELECT id, cola FROM B WHERE colb > 1000;
要求:目標欄位列表與 SELECT 選項數量、順序、型別一一對應。
場景:批量插入時,主鍵/唯一鍵衝突的行靜默跳過,不中斷執行、不報錯。
INSERT IGNORE INTO A (id, cola)
SELECT id, cola FROM B WHERE colb > 1000;
行為:
affected_rows 不計入。場景:表 C 資料同步到表 A,主鍵衝突時更新指定欄位。
INSERT INTO A (id, cola)
SELECT id, cola FROM C
ON DUPLICATE KEY UPDATE A.cola = C.cola;
進階用法:
-- 更新多欄位,使用 VALUES() 參考插入值
INSERT INTO A (id, cola, colb, updated_at)
SELECT id, cola, colb, NOW() FROM C
ON DUPLICATE KEY UPDATE
cola = VALUES(cola),
colb = VALUES(colb),
updated_at = VALUES(updated_at);
-- 計數器累加
INSERT INTO stats (date, cnt) VALUES ('2023-01-01', 1)
ON DUPLICATE KEY UPDATE cnt = cnt + 1;
| 語法 | 衝突行處理 | 適用場景 | 效能 |
|---|---|---|---|
INSERT SELECT | 報錯中斷 | 確知無衝突的資料遷移 | 最快 |
INSERT IGNORE SELECT | 靜默跳過 | 冪等導入、日誌表去重 | 略慢(需檢查鍵) |
INSERT ... ON DUPLICATE KEY UPDATE | 更新指定欄位 | 資料同步、計數器、Upsert | 最慢(含更新邏輯) |
ON DUPLICATE KEY UPDATE 觸發條件為主鍵或唯一索引衝突,普通索引不觸發。VALUES(col) 僅在 ON DUPLICATE KEY UPDATE 子句中有效,參考原插入值。INSERT IGNORE 會吞沒所有錯誤(含資料截斷、外鍵失敗),調試困難,生產慎用。