在 MySQL 中,ON DUPLICATE KEY UPDATE
是一个非常实用的语法,用来实现**“存在则更新,不存在则插入”**的逻辑,尤其在批量导入或同步数据时很常用。
1. 基本语法
INSERT INTO table_name (col1, col2, ...)
VALUES (val1, val2, ...)
ON DUPLICATE KEY UPDATE col1 = new_val1, col2 = new_val2;
- 触发条件:插入时遇到主键(PRIMARY KEY)或唯一索引(UNIQUE KEY)冲突
- 执行逻辑:
- 没有冲突 → 正常插入
- 有冲突 → 执行
UPDATE
中的更新语句
2. 示例
假设有一个用户表:
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT,
UNIQUE KEY unique_name (name)
);
插入或更新
INSERT INTO users (id, name, age)
VALUES (1, 'Alice', 20)
ON DUPLICATE KEY UPDATE age = VALUES(age);
- 如果
id=1
或name='Alice'
已存在 → 更新age
- 否则 → 插入新数据
3. 使用 VALUES()
引用插入值
在 UPDATE
部分,可以直接用 VALUES(col_name)
引用插入时提供的值:
ON DUPLICATE KEY UPDATE
age = VALUES(age),
name = VALUES(name);
MySQL 8.0.19+ 中 VALUES()
已废弃,改用 NEW.col_name
或 AS
语法:
INSERT INTO users (id, name, age)
VALUES (1, 'Alice', 25) AS new
ON DUPLICATE KEY UPDATE age = new.age;
4. 批量插入 + 更新
INSERT INTO users (id, name, age)
VALUES
(1, 'Alice', 25),
(2, 'Bob', 30),
(3, 'Cathy', 28)
ON DUPLICATE KEY UPDATE
age = VALUES(age);
一次插入多条记录,如果冲突则批量更新。
5. 常用技巧
自增字段计数
INSERT INTO stats (id, count)
VALUES (1, 1)
ON DUPLICATE KEY UPDATE count = count + 1;
如果存在则计数加一。
更新多个字段
ON DUPLICATE KEY UPDATE
name = VALUES(name),
age = VALUES(age),
last_update = NOW();
和唯一索引配合
ON DUPLICATE KEY UPDATE
依赖主键或唯一索引冲突
例如:
CREATE UNIQUE INDEX uniq_email ON users(email);
这样用 email 冲突时也能触发更新。
6. 注意事项
- 必须有主键或唯一索引才能触发
- 可能会触发 两次写入(一次尝试插入,一次更新),所以会影响自增 ID
- 如果不希望影响
AUTO_INCREMENT
,可考虑INSERT ... ON DUPLICATE KEY UPDATE id=id
- MySQL 8.0.19+ 推荐用
AS new
代替VALUES()
发表回复