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_id和product_id的组合已存在,则更新quantity和price。
    • VALUES(price)表示引用插入时的值。

(2) UPSERT(通用概念)

  • 定义 :数据库操作的通用术语,表示"插入或更新"(U pdate or Insert),是SQL标准中定义的原子操作。
  • 不同数据库的实现 :
    • PostgreSQL :INSERT ... ON CONFLICT DO UPDATE
    • SQLite :INSERT OR REPLACE 或 ON CONFLICT
    • Oracle :MERGE语句
    • SQL Server :MERGE语句
    • JPA/Hibernate :通过@Entity的@DynamicUpdate或saveOrUpdate方法模拟。

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。
相关推荐
standxy8 分钟前
索引设计实战:pgvector HNSW × JSONB GIN × 复合索引
数据库·开发
guo_wen_qiang18 分钟前
使用spring-data-mongodb操作mongo记录
数据库·mongodb
凤山老林25 分钟前
授权模型只会RBAC?深入 ABAC 授权模型,实现权限判断做成策略引擎
大数据·数据库·算法
geovindu28 分钟前
sql:SQL Views and Materialized Views using mysql 9.0
大数据·数据库·数据仓库·sql·mysql·数据库开发·数据库架构
梦影_42 分钟前
MySQL进阶教程(二)—— 储存过程与触发器(下)
开发语言·数据库·后端·sql·mysql·oracle·数据库开发
工业涂料百问1 小时前
陶瓷涂料的光泽度怎么检测?20°、60°、85° 三个角度怎么选
数据库
仙逆GPT1 小时前
ChatGPT、Codex工程实战:Agent把OFFSET分页改成游标分页,查询更快了,为什么数据反而会重复和丢失?
mysql·chatgpt·codex·chatgptplus·chatgptpro
科创致远1 小时前
ESOP 电子作业指导书车间无纸化实战评测
大数据·数据库·人工智能·制造
xiaomuzuirenzhen1 小时前
2027车企数字化岗位项目准备:从SQL数据建模到库存分析看板
大数据·数据库·sql
鸽芷咕1 小时前
从环境搭建到敬礼动作:启元 Q1 SDK 全流程实战与 8 个实测坑排查手册
数据库·ai·机器人·sdk·启元q1