MySQL中insertOrUpdate的功能实现方式

 更新时间:2025年12月18日 11:02:56   作者:_派大星  
文章介绍了MySQL中实现`insertOrUpdate`功能的`INSERT INTO...ON DUPLICATE KEY UPDATE`语句,并探讨了其工作原理、执行流程以及潜在的死锁问题,同时,还提到了类似SQL语句如`REPLACE INTO`和`INSERT IGNORE INTO`的区别,并讨论了主键跳跃的现象

insertOrUpdate在我们日常使用中比较常见,那么它是如何实现的呢,不知道大家有没有考虑过呢?

在MySQL中,可采用INSERT INTO ... ON DUPLICATE KEY UPDATE语句实现insertOrUpdate功能。

值得留意的是,在出现重复键时,会在先前索引值和当前值之间添加临时键锁,这可能导致死锁。

若要使用INSERT INTO … ON DUPLICATE KEY UPDATE语句,需满足以下条件:

  • 表必须具有主键或唯一索引;
  • 插入的数据必须包含主键或唯一索引列;
  • 主键或唯一索引列的值不能为NULL。

举个例子:

设想有一张student表,包括id、name和age三列,其中id是主键。现在要插入一条数据,若该数据的主键已存在,则更新该数据的姓名和年龄,否则插入该数据。

INSERT INTO student (id, name, age) VALUES (1, 'Paidaxing', 20)
ON DUPLICATE KEY UPDATE name='Paidaxing', age=18;

底层实现

使用INSERT INTO ... ON DUPLICATE KEY UPDATE语句,如果数据库中已存在具有相同唯一索引或主键的记录,则更新该记录。

其底层原理和执行流程如下:

  • 检查唯一索引或主键:执行INSERT INTO ... ON DUPLICATE KEY UPDATE语句时,数据库首先尝试插入新行。在此过程中,数据库会检查表中是否存在与新插入行具有相同的唯一索引或主键的记录。
  • 冲突处理:如果不存在冲突的唯一索引或主键,新行将被正常插入。如果存在冲突,即发现重复的唯一索引或主键值,数据库将不会插入新行,而是转而执行更新操作。
  • 执行更新:在检测到唯一索引或主键的冲突后,数据库将根据ON DUPLICATE KEY UPDATE后面指定的列和值来更新已存在的记录。这里可以指定一个或多个列进行更新,并且可以使用VALUES函数引用原本尝试插入的值。

相似SQL

除了INSERT INTO … ON DUPLICATE KEY UPDATE之外,还有一些类似的SQL语句,比如:

  • REPLACE INTO:如果存在唯一索引冲突,则先删除旧记录,再插入新记录。
  • INSERT IGNORE INTO:如果唯一索引冲突,则忽略该条插入操作,不报错。

浅谈主键跳跃

在MySQL中使用INSERT ON DUPLICATE KEY UPDATE语句时,如果插入操作失败(因为主键或唯一键冲突),而执行了更新操作,确实会导致自增主键计数器增加,即使没有实际插入新记录。

这是因为MySQL在尝试插入新记录时,会先分配一个新的自增主键值,无论后续是插入成功还是执行更新操作,这个主键值都已经被分配并且会增加。

例如,假设有一个表test定义如下:

CREATE TABLE test (
    id INT AUTO_INCREMENT PRIMARY KEY,
    value VARCHAR(255),
    UNIQUE KEY unique_value (value)
);

然后执行以下语句:

INSERT INTO test (value) VALUES ('a') 
ON DUPLICATE KEY UPDATE value = 'a';

再执行一次:

此时,由于value列存在唯一键约束,并且已经存在一条记录value=‘a’,所以不会插入新记录,而是会执行更新操作。但即便如此,自增主键id的计数器依然会增加。

然后再插入一条新的记录:

这意味着下一次插入新记录时,自增主键的值会比之前增加,即2已经被用过了,虽然没插入成功,但是新的记录就直接用3了。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mysql 5.7 安装配置方法图文教程

    mysql 5.7 安装配置方法图文教程

    这篇文章主要为大家分享了mysql 5.7 安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • MySQL连接池DataSource的使用及实践

    MySQL连接池DataSource的使用及实践

    DruidDataSource作为一款优秀的数据库连接池组件,不仅提供了高效的连接管理,还包含了丰富的监控和诊断功能,本文主要介绍了MySQL连接池DataSource的使用及实践,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • MySQL 5.7.20绿色版安装详细图文教程

    MySQL 5.7.20绿色版安装详细图文教程

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle旗下产品。这篇文章主要介绍了MySQL 5.7.20绿色版安装详细图文教程,需要的朋友可以参考下
    2017-11-11
  • mysql_mcp_server部署及应用实践案例

    mysql_mcp_server部署及应用实践案例

    文章介绍了在CentOS7.5环境下部署MySQL_mcp_server的步骤,包括服务安装、配置和启动,还提供了一个基于Dify工作流的应用案例,展示了如何在Dify中安装和使用MCP服务,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接

    深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接

    本篇文章是对SQL中的四种连接-左外连接、右外连接、内连接、全连接进行了详细的分析介绍,需要的朋友参考下
    2013-07-07
  • MySQL优化GROUP BY(松散索引扫描与紧凑索引扫描)

    MySQL优化GROUP BY(松散索引扫描与紧凑索引扫描)

    这篇文章主要介绍了MySQL优化GROUP BY(松散索引扫描与紧凑索引扫描),需要的朋友可以参考下
    2016-05-05
  • MySQL 日期时间加减的示例代码

    MySQL 日期时间加减的示例代码

    本文主要介绍了MySQL日期时间加减,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • MySQL数据库中sql表设计的注意事项

    MySQL数据库中sql表设计的注意事项

    实际开发中一个项目通常需要很多张表才能完成,这篇文章主要给大家介绍了关于MySQL数据库中sql表设计的注意事项,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-05-05
  • 详解MySQL主从不一致情形与解决方法

    详解MySQL主从不一致情形与解决方法

    这篇文章主要介绍了详解MySQL主从不一致情形与解决方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • MySQL REVOKE实现删除用户权限

    MySQL REVOKE实现删除用户权限

    在 MySQL 中,可以使用 REVOKE 语句删除某个用户的某些权限,本文就详细的来介绍一下REVOKE 的具体使用方法,感兴趣的可以了解一下
    2021-06-06

最新评论