答案:INSERT ON DUPLICATE KEY UPDATE 用于处理唯一键或主键冲突时执行更新操作。当插入数据存在冲突则更新指定字段,否则插入新记录,适用于存在则更新、不存在则插入的场景,如用户登录统计,需确保表上有唯一索引或主键,利用VALUES()获取插入值,可避免竞争条件并提升效率。

在 mysql 中,INSERT ON DUPLICATE KEY UPDATE 是一种非常实用的语句,用于在插入数据时,如果遇到唯一键或主键冲突,就执行更新操作,而不是报错。这个功能特别适合处理“存在则更新,不存在则插入”的场景。
基本语法
该语句的基本结构如下:
INSERT intO table_name (column1, column2, …) VALUES (value1, value2, …) ON DUPLICATE KEY UPDATE column1 = VALUES(column1), column2 = VALUES(column2), …;
说明:
- 当插入的数据导致唯一索引或主键冲突时,MySQL 会执行 UPDATE 部分。
- 如果没有冲突,则正常插入新记录。
- VALUES(column) 表示你尝试插入的值,不是当前表中的值。
使用场景示例
假设有一个用户登录统计表:
CREATE TABLE user_stats ( user_id INT PRIMARY KEY, login_count INT default 0, last_login DATETIME );
我们希望每次用户登录时:
- 如果 user_id 不存在,就插入一条新记录,login_count 为 1。
- 如果已存在,就将 login_count 加 1,并更新最后登录时间。
可以这样写:
INSERT INTO user_stats (user_id, login_count, last_login) VALUES (1001, 1, NOW()) ON DUPLICATE KEY UPDATE login_count = login_count + 1, last_login = NOW();
第一次执行:插入 user_id=1001 的记录。
第二次执行:发现主键冲突,于是更新 login_count 和 last_login。
注意事项与技巧
- 必须有唯一索引(UNIQUE)或主键(PRIMARY KEY),否则不会触发“duplicate key”错误,也就不会执行 UPDATE。
- UPDATE 中可以引用 VALUES() 函数获取插入时的值,比如 VALUES(login_count) 返回的是你试图插入的那个值。
- 可以只更新部分字段,不需要更新所有列。
- 如果 UPDATE 后的值和原值一样,MySQL 可能仍会认为发生了“变更”,影响 affected rows 的返回值(通常变为 2)。
实际应用建议
基本上就这些。只要表上有唯一约束,就可以安全使用 INSERT ON DUPLICATE KEY UPDATE 来简化逻辑。不复杂但容易忽略细节,比如 VALUES() 的用法。