首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL INSERT ... ON DUPLICATE KEY UPDATE 實現 Oracle MERGE 型 Upsert

     編輯:MySQL 資料庫相關知識

MySQL 無 MERGE 語句,但 INSERT ... ON DUPLICATE KEY UPDATE 可實現相同「存在更新、不存在插入」邏輯,且為單條原子 SQL,無競態風險。

單欄更新

INSERT INTO tbl (columnA, columnB, columnC)
VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE
  columnA = IF(columnB > 0, 1, columnA);

多欄更新

INSERT INTO tbl (columnA, columnB, columnC)
VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE
  columnA = IF(columnB > 0, 1, columnA),
  columnB = IF(columnC > 0, 1, columnB),
  columnC = IF(columnA > 0, 1, columnC);

關鍵特性

  • 原子性:單條語句,無「查-改」間隙
  • 智能優化:若 UPDATE 值與原值相同,InnoDB 不寫入、不產生 Redo、不加鎖,零開銷
  • VALUES() 函數:引用插入值,避免重複字面量

前置條件

目標表必須有 PRIMARY KEY 或 UNIQUE INDEX,否則永遠走 INSERT 分支。

對比 Oracle MERGE

特性Oracle MERGEMySQL ON DUPLICATE KEY UPDATE
語法複雜度較複雜(USING/WHEN MATCHED/NOT MATCHED)簡潔(單條 INSERT + UPDATE 子句)
多表關聯支援複雜 JOIN單表,需應用層組裝值
效能優化器深度優化極優(單表、主鍵查找)
可移植性Oracle 專有MySQL/MariaDB/Percona 通用

實戰範本

INSERT INTO user_device (user_id, device_token, last_login, login_count)
VALUES (?, ?, NOW(), 1)
ON DUPLICATE KEY UPDATE
  device_token = VALUES(device_token),
  last_login   = VALUES(last_login),
  login_count  = login_count + 1;

掌握此模式,單表 Upsert 不再需要應用層 SELECT ... IF EXISTS UPDATE ELSE INSERT 反模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved