數據操作語言(DML)是業務邏輯落地的核心。MySQL在標準SQLINSERT/UPDATE/DELETE基礎上擴展了REPLACE,提供了處理主鍵衝突的原子化方案。本文深度解析INSERT與REPLACE的語法變體、行為差異、性能特徵及工程落地指南。
INSERT:多樣化的插入語法
語法變體一:標準VALUES形式
INSERT INTO users (id, username, email, status)
VALUES (1001, 'zhangsan', 'zs@example.com', 1);
- 列名與值一一對應,順序可調整
- 省略列名則需按表定義順序全列賦值
- 自增主鍵可省略或指定
DEFAULT/NULL
語法變體二:SET形式(MySQL擴展)
INSERT INTO users SET
username = 'lisi',
email = 'ls@example.com',
status = 1;
- 列名值成對出現,可讀性強,適合動態構建
- 至少賦值一列,未指定列用默認值
- 不支持多行插入
語法變體三:多行批量插入(MySQL擴展,高性能關鍵)
INSERT INTO users (username, email, status) VALUES
('user1', 'u1@ex.com', 1),
('user2', 'u2@ex.com', 1),
('user3', 'u3@ex.com', 1);
-- 單條SQL插入N行,減少網絡往返與解析優化開銷
- 每行值用括號包裹,逗號分隔
- 單條SQL建議500-2000行,超大批次分批提交
- 配合
LOAD DATA INFILE可達百萬級秒級導入
特殊形式
-- 全默認值插入(表需全列有默認值)
INSERT INTO users () VALUES ();
-- 指定分區插入(分區表)
INSERT INTO sales PARTITION (p2024_q1) VALUES (...);
REPLACE:主鍵衝突的「覆蓋式插入」
核心機制
- 嘗試插入新行
- 若無主鍵/唯一鍵衝突 → 等同
INSERT
- 若有衝突 → 刪除舊行 + 插入新行(原子操作)
- 返回影響行數:1=純插入,2=1刪+1插,>2=多唯一索引觸發多行刪除
前置條件
- 表必須有主鍵或非空唯一索引
- 衝突判斷基於所有唯一索引(含主鍵)
語法形式
-- VALUES形式
REPLACE INTO users (id, username, email) VALUES (1001, 'zhangsan_new', 'zs_new@ex.com');
-- SET形式
REPLACE INTO users SET id=1001, username='zhangsan_new', email='zs_new@ex.com';
-- 多行(慎用,見下文陷阱)
REPLACE INTO users (id, username) VALUES (1, 'a'), (2, 'b');
INSERT vs REPLACE:關鍵差異對比
| 維度 | INSERT | REPLACE |
| 衝突行為 | 報錯(Duplicate entry) | 刪舊插新(靜默覆蓋) |
| 原子性 | 單行原子 | 刪+插組合原子 |
| 部分更新 | 支持(ON DUPLICATE KEY UPDATE) | 不支持(全行替換) |
| 自增ID | 衝突不消耗ID | 刪除舊行,新行用新ID(可能導致ID跳躍) |
| 外鍵關聯 | 衝突不影響子表 | 刪除父行觸發ON DELETE動作(級聯刪除/置NULL) |
| 觸發器 | 觸發BEFORE/AFTER INSERT | 觸發BEFORE/AFTER DELETE + INSERT |
| 性能 | 單純插入快 | 衝突時雙倍開銷 |
最佳實踐:ON DUPLICATE KEY UPDATE(推薦替代REPLACE)
INSERT INTO users (id, username, email, login_count, last_login)
VALUES (1001, 'zhangsan', 'zs@ex.com', 1, NOW())
ON DUPLICATE KEY UPDATE
login_count = login_count + 1,
last_login = NOW(),
email = VALUES(email); -- 可選:更新郵箱
- 精確控制衝突時更新哪些列
- 保留自增ID不變,避免外鍵級聯副作用
- 性能優於REPLACE(無刪除操作)
VALUES(col)引用插入值,避免重複寫字面量
工程落地避坑指南
- 批量插入優先:業務允許時,攒批
INSERT ... VALUES (...),(...),...,配合事務邊界控制
- 幂等設計用ON DUPLICATE KEY UPDATE:去重寫入、計數器增量、狀態機流轉
- 慎用REPLACE:僅用於「全行替換語義明確、無外鍵依賴、可接受ID變更」場景
- 大批次分塊:>2000行分批,單事務<1秒,避免長事務阻塞
- 監控影響行數:應用層校驗
affected_rows,異常報警
性能對比實測參考(10萬行,主鍵衝突率30%)
| 方案 | 耗時 | 備註 |
| 單條INSERT循環 | 45秒 | 網絡往返殺手 |
| 批量INSERT (1000行/批) | 2.1秒 | 衝突報錯需捕獲重試 |
| REPLACE批量 | 3.8秒 | 衝突觸發刪除開銷 |
| INSERT ... ON DUPLICATE KEY UPDATE批量 | 2.3秒 | 最佳平衡 |
| LOAD DATA INFILE | 0.8秒 | 極速導入,需文件權限 |