表必須擁有 主鍵 或 唯一索引,否則無法判斷「重複」。
INSERT IGNORE INTO `table_name` (`email`, `phone`, `user_id`)
VALUES ('test9@163.com', '99999', '9999');
INSERT IGNORE INTO t1 (name) SELECT name FROM t2;REPLACE INTO `table_name` (`col_name`, ...) VALUES (...);
REPLACE INTO `table_name` (`col_name`, ...) SELECT ...;
REPLACE INTO `table_name` SET `col_name` = 'value', ...;
執行邏輯:
返回值: 受影響行數 = 刪除行數 + 插入行數。
1 表示純插入,≥2 表示發生替換。
注意: 會觸發 DELETE + INSERT 觸發器,自增 ID 會改變。
INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE `c` = `c` + 1;
等價於:
UPDATE `table` SET `c` = `c` + 1 WHERE `a` = 1;
多行插入技巧:
INSERT INTO `table` (`a`, `b`, `c`) VALUES (1,2,3), (4,5,6)
ON DUPLICATE KEY UPDATE `c` = VALUES(`a`) + VALUES(`b`);
VALUES(col) 可引用插入值,極適合批次 upsert。
| 受影響行數 | 含義 |
|---|---|
| 1 | 新增 1 行 |
| 2 | 更新 1 行(刪 1 + 插 1) |
| >2 | 多行操作或多重唯一鍵衝突 |
INSERT INTO `table_name1` (`title`, `first_name`, `last_name`, `email`, `phone`, `user_id`, `role_id`, `status`, `campaign_id`)
SELECT '', '', '', `table_name2`.`email`, `table_name2`.`phone`, NULL, NULL, 'pending', 29
FROM `table_name2`
WHERE `table_name2`.`status` = 1
ON DUPLICATE KEY UPDATE `table_name1`.`status` = 'pending';
DELAYED:非阻塞插入,犧牲一致性換吞吐。IGNORE:僅關注主鍵/唯一鍵不存在則插入,存在則忽略。MySQL 中 UNIQUE 索引不包含 NULL。以下可重複插入:
INSERT INTO `test` (`a`) VALUES (NULL); -- 可重複執行
聯合唯一索引同理,任何欄位為 NULL 都不會觸發衝突。
| 場景 | 推薦方案 |
|---|---|
| 大量導入、允許靜默跳過 | INSERT IGNORE |
| 需保留最新資料、自增 ID 不重要 | REPLACE INTO |
| 需精準控制更新邏輯、保留自增 ID | ON DUPLICATE KEY UPDATE |