news 2026/4/18 11:47:06

insertOnDuplicateKey 和 upsert 区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
insertOnDuplicateKey 和 upsert 区别

二者是一样的

insertOnDuplicateKey 实际上是 ON DUPLICATE KEY UPDATE,是MySQL的特有写法

类似的有 ON CONFICT() ,这个是 pgsql 的类似写法

在数据库操作中,INSERT ON DUPLICATE KEY UPDATE(MySQL特有语法)和UPSERT(通用概念,不同数据库实现不同)都是用于处理“如果记录存在则更新,不存在则插入”的场景。以下是它们的详细对比和关键区别:


1. 核心概念

(1)INSERT ON DUPLICATE KEY UPDATE(MySQL)

  • 定义:MySQL特有的SQL语法,当插入数据时违反唯一键(UNIQUE KEY)或主键约束时,自动执行更新操作。
  • 适用场景:仅适用于MySQL及其衍生数据库(如MariaDB)。
  • 示例

    sql

    INSERT INTO orders (order_id, product_id, quantity, price) VALUES (1, 100, 5, 10.0) ON DUPLICATE KEY UPDATE quantity = quantity + 1, price = VALUES(price);
    • 如果order_idproduct_id的组合已存在,则更新quantityprice
    • VALUES(price)表示引用插入时的值。

(2)UPSERT(通用概念)

  • 定义:数据库操作的通用术语,表示“插入或更新”(Update orInsert),是SQL标准中定义的原子操作。
  • 不同数据库的实现
    • PostgreSQLINSERT ... ON CONFLICT DO UPDATE
    • SQLiteINSERT OR REPLACEON CONFLICT
    • OracleMERGE语句
    • SQL ServerMERGE语句
    • JPA/Hibernate:通过@Entity@DynamicUpdatesaveOrUpdate方法模拟。

2. 关键区别

对比项INSERT ON DUPLICATE KEY UPDATE(MySQL)UPSERT(通用实现)
语法来源MySQL特有SQL标准概念,不同数据库实现不同
冲突条件仅基于唯一键或主键冲突可基于唯一约束、主键或其他条件(如PostgreSQL的ON CONFLICT (column)
更新范围只能更新冲突行的字段可灵活控制更新哪些字段(如PostgreSQL的DO UPDATE SET
多行冲突处理逐行处理冲突,每行独立判断某些数据库(如PostgreSQL)支持批量冲突处理
返回值返回受影响的行数(插入或更新)返回值因数据库而异(如PostgreSQL返回特殊状态)
跨数据库兼容性仅MySQL/MariaDB支持需根据数据库调整语法(如PostgreSQL/Oracle)

3. 具体数据库实现对比

(1) MySQL

sql

-- 插入或更新(基于唯一键冲突) INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com') ON DUPLICATE KEY UPDATE name = VALUES(name), email = VALUES(email);
  • 特点:简单直接,但仅限MySQL。

(2) PostgreSQL

sql

-- 插入或更新(基于唯一约束冲突) INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, email = EXCLUDED.email;
  • 特点
    • ON CONFLICT (column)指定冲突条件。
    • EXCLUDED表引用插入时的值。

(3) SQLite

sql

-- 方式1:替换整行(危险!可能丢失数据) INSERT OR REPLACE INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com'); -- 方式2:条件更新(更安全) INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com') ON CONFLICT(id) DO UPDATE SET name = excluded.name;
  • 注意OR REPLACE会删除旧行再插入新行,可能导致外键约束问题。

(4) Oracle/SQL Server

sql

-- Oracle/SQL Server使用MERGE语句 MERGE INTO users target USING (SELECT 1 AS id, 'Alice' AS name, 'alice@example.com' AS email FROM dual) source ON (target.id = source.id) WHEN MATCHED THEN UPDATE SET target.name = source.name, target.email = source.email WHEN NOT MATCHED THEN INSERT (id, name, email) VALUES (source.id, source.name, source.email);
  • 特点:功能强大,但语法复杂。

4. 如何选择?

  • MySQL项目:直接用INSERT ON DUPLICATE KEY UPDATE,简单高效。
  • 跨数据库项目
    • 使用JPA/Hibernate的saveOrUpdate(需实体类配置正确)。
    • 或根据数据库类型动态生成SQL(如PostgreSQL用ON CONFLICT,Oracle用MERGE)。
  • 高并发场景:注意锁竞争问题(如MySQL的INSERT ... ON DUPLICATE KEY可能引发间隙锁)。

5. 代码示例(Spring Data JPA)

如果使用Spring Data JPA,可以通过以下方式模拟UPSERT:

java

@Repository public interface UserRepository extends JpaRepository<User, Long> { @Modifying @Query(value = "INSERT INTO users (id, name, email) " + "VALUES (:id, :name, :email) " + "ON CONFLICT (id) DO UPDATE SET name = :name, email = :email", nativeQuery = true) void upsertUser(@Param("id") Long id, @Param("name") String name, @Param("email") String email); }
  • 注意:需启用@Modifying和事务(@Transactional)。

总结

  • INSERT ON DUPLICATE KEY UPDATE:MySQL专属,简单直接。
  • UPSERT:通用概念,需根据数据库选择具体实现(如PostgreSQL的ON CONFLICT、Oracle的MERGE)。
  • 跨数据库兼容性:优先考虑JPA/Hibernate或抽象层,避免硬编码SQL。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 6:41:53

海外短剧APP+H5跨端开发实战:从架构设计到落地实现

一、项目背景与市场机遇近年来&#xff0c;海外短剧市场迎来爆发式增长&#xff0c;用户对“快节奏、强剧情”内容的需求激增。本项目采用跨端开发架构&#xff0c;打造同时覆盖iOS、Android和Web的短剧平台&#xff0c;实现一套代码多端运行&#xff0c;大幅提升开发效率。二、…

作者头像 李华
网站建设 2026/4/18 4:03:04

uWebSockets性能监控实战:从零构建企业级告警体系

还在为实时应用的性能问题头疼不已&#xff1f;当用户连接数飙升时&#xff0c;你是否能第一时间发现异常&#xff1f;本文将带你深入探索uWebSockets的高效监控方案&#xff0c;通过实战案例教你如何搭建完整的性能监控与告警系统。 【免费下载链接】uWebSockets 项目地址:…

作者头像 李华
网站建设 2026/4/18 4:02:13

Armv7的寄存器介绍

一、介绍ARMv7 架构下核心寄存器分为通用寄存器、程序状态寄存器、专用寄存器三类&#xff0c;不同模式下部分寄存器有备份&#xff08;banked&#xff09;&#xff0c;作用如下&#xff1a;1. 通用寄存器 (R0-R15)- R0-R7&#xff1a;未备份通用寄存器&#xff0c;所有处理器模…

作者头像 李华
网站建设 2026/4/18 0:36:03

大学生找工作压力大?另辟新径转行网络安全实现弯道超车!

现在大学生找工作压力大吗&#xff1f;这个问题是毋庸置疑的&#xff0c;不仅大学生找工作压力大&#xff0c;已经有多年工作经验的职场老鸟压力也非常大。 2023年&#xff0c;我国搞笑毕业生人数预计达到1158万人&#xff0c;再创新高&#xff0c;堪称史上最难就业季。据国家统…

作者头像 李华
网站建设 2026/4/18 4:01:03

Axure RP 11中文界面配置指南:Mac用户的5分钟快速设置方案

想要在Mac上享受完整中文界面的Axure RP 11设计体验吗&#xff1f;本指南专为Mac用户量身定制&#xff0c;通过简洁明了的步骤&#xff0c;帮助您在5分钟内完成Axure RP 11中文语言包的配置安装&#xff0c;彻底告别英文界面的困扰&#xff0c;显著提升原型设计的工作效率。 【…

作者头像 李华
网站建设 2026/4/18 4:03:26

测试团队领导力的培养方法

在快速发展的软件行业中&#xff0c;测试团队作为质量保障的核心&#xff0c;其领导力水平直接决定了项目的成功与否。本文针对软件测试从业者&#xff0c;探讨测试团队领导力的内涵、关键培养要素及实践策略&#xff0c;旨在帮助团队领导者构建高效、协作的测试环境&#xff0…

作者头像 李华