告别重复数据烦恼!MySQL ON DUPLICATE KEY UPDATE 优雅解决存在更新/不存在插入难题

告别重复数据烦恼!MySQL ON DUPLICATE KEY UPDATE 优雅解决存在更新/不存在插入难题

目录

前言

在日常的数据库操作中,我们经常会遇到这样的场景:“如果数据存在,就更新它;如果不存在,就插入一条新的”。这种模式通常被称为 “Upsert”(Update + Insert)。在 MySQL 中,实现 Upsert 最优雅、最高效的方式之一就是使用 ON DUPLICATE KEY UPDATE 语法。

一、基本概念

1、什么是 ON DUPLICATE KEY UPDATE?

ON DUPLICATE KEY UPDATE是 MySQL 特有的一种 INSERT 语句扩展,当执行 INSERT 操作时,如果插入的数据与表中已有数据的主键(PRIMARY KEY)​或唯一索引(UNIQUE INDEX)​发生冲突(即要插入的值与已有记录的主键或唯一索引值相同),则不执行插入操作,而是转而执行 UPDATE 操作,更新已存在的记录。

2、工作原理

  1. 尝试插入​:MySQL 首先尝试按照正常的 INSERT 语句插入新记录
  2. 检查冲突​:在插入前,MySQL 会检查是否存在与待插入数据主键或唯一索引冲突的记录
  3. 冲突处理​:
    • 如果没有冲突:正常插入新记录
    • 如果有冲突:不插入新记录,而是根据 ON DUPLICATE KEY UPDATE子句更新已存在的记录

3、基本语法

基本语法格式如下:

INSERTINTO table_name (column1, column2,..., columnN)VALUES(value1, value2,..., valueN)ONDUPLICATEKEYUPDATE column1 = value1, column2 = value2,...;

更常用的写法是使用 VALUES() 函数来引用原本打算插入的值:

INSERTINTO table_name (column1, column2,..., columnN)VALUES(value1, value2,..., valueN)ONDUPLICATEKEYUPDATE column1 =VALUES(column1), column2 =VALUES(column2),...;
⚠️触发条件:只有当插入操作违反了 主键(PRIMARY KEY) 或 唯一索引(UNIQUE INDEX) 约束时,UPDATE 部分才会被执行

二、使用场景

1、计数器更新

  • 最常见的应用场景是实现计数器功能,如文章浏览量、点赞数等
INSERTINTO article_views (article_id, view_count)VALUES(123,1)ONDUPLICATEKEYUPDATE view_count = view_count +1;

2、配置项更新

  • 当需要更新或插入配置项时
INSERTINTO system_config (config_key, config_value, last_updated)VALUES('site_title','My Website',NOW())ONDUPLICATEKEYUPDATE config_value =VALUES(config_value), last_updated =NOW();

3、购物车商品更新

  • 添加商品到购物车,已存在则更新数量
INSERTINTO shopping_cart (user_id, product_id, quantity)VALUES(123,456,2)ONDUPLICATEKEYUPDATE quantity = quantity +VALUES(quantity), added_at =CURRENT_TIMESTAMP;
⚠️必须添加主键或唯一索引,否则ON DUPLICATE KEY UPDATE将不会触发,语句会正常执行插入操作(如果无其他错误)

三、高级用法

1、条件更新

  • 在 ON DUPLICATE KEY UPDATE子句中使用条件表达式
-- 这个例子只在新的价格更低时才更新价格INSERTINTO products (product_id, price, last_updated)VALUES(101,99.99,NOW())ONDUPLICATEKEYUPDATE price =IF(VALUES(price)< price,VALUES(price), price), last_updated =NOW();

2、多表关联

  • 虽然不能直接在 ON DUPLICATE KEY UPDATE中使用多表,但可以结合子查询
INSERTINTO user_stats (user_id, login_count)SELECT123,1FROM dual WHERENOTEXISTS(SELECT1FROM users WHERE id =123)ONDUPLICATEKEYUPDATE login_count = login_count +1;

3、批量操作优化

  • 对于大量数据的批量插入/更新,考虑以下优化
INSERTINTO log_entries (user_id,action,timestamp)VALUES(1,'login',NOW()),(2,'view',NOW()),(3,'purchase',NOW())ONDUPLICATEKEYUPDATEaction=VALUES(action),timestamp=VALUES(timestamp);
⚠️当表有多个唯一约束时,任何唯一键冲突都会触发UPDATE

四、其他处理冲突的方案

1、REPLACE INTO

  • 实际上是先DELETE再INSERT,主键会有变化
REPLACEINTO users (email, name, login_count)VALUES('[email protected]','Test User',1);

2、INSERT IGNORE

  • 冲突时直接忽略,不更新
INSERTIGNOREINTO users (email, name)VALUES('[email protected]','Test User');

Read more

【金仓数据库】ksql 指南(五) —— 创建与管理索引和视图(KingbaseES 查询优化核心)

【金仓数据库】ksql 指南(五) —— 创建与管理索引和视图(KingbaseES 查询优化核心)

引言 掌握表的基本运作之后,若想优化查询效率并简化数据访问,就要去学习“索引”和“视图”的运用,索引类似于“书籍目录”,可以极大地加快查询速度;视图类似“数据窗口”,能够隐藏复杂的查询逻辑,还能控制数据的可见性。本文就“ksql命令行操作索引与视图”展开论述,把从“作用到创建,再到查看,维持直至删除”的全过程拆解成实际操作步骤,并结合例子和避坑提示,以使初学者能够领悟并付诸实行。 文章目录 * 引言 * 一、前置准备:确认操作基础(衔接前文,确保连贯) * 1.1 1. 连接数据库并切换目标模式 * 1.2 2. 插入测试数据(用于验证索引 / 视图效果) * 二、索引管理:给表 “加目录”,加速查询 * 2.1 1.

By Ne0inhk
从 Express 到企业级架构:NestJS 实战指南与深度解析

从 Express 到企业级架构:NestJS 实战指南与深度解析

在 Node.js 的后端开发生态中,Express 长期以来以其极简主义占据统治地位。然而,随着项目规模的扩大,缺乏约束的“自由”往往会导致代码结构混乱,也就是我们常说的“意大利面条式代码”。 为了解决这个问题,NestJS 应运而生。NestJS 是一个用于构建高效、可扩展且易于维护的企业级后端应用的框架。它基于 TypeScript 构建,深受 Angular 架构的影响,引入了模块化、依赖注入(DI)和装饰器等先进概念。 本文将结合一个包含待办事项(Todos)管理和 PostgreSQL 数据库连接的实战 Demo,带你深入理解 NestJS 的核心架构。 一、 为什么选择 NestJS? 在开始写代码之前,我们需要理解 NestJS 试图解决什么问题。 1. 架构标准化:Express 让你自己决定文件放哪,而

By Ne0inhk
Go语言零基础小白学习知识点【基础版详解】

Go语言零基础小白学习知识点【基础版详解】

✅ 纯白话拆解+代码示例+实战场景,零基础能直接照着敲 ✅ 技术适配:基于Go 1.23(LTS长期支持版,企业主流),聚焦高并发、云原生核心场景 ✅ 条理清晰:从“环境搭建→基础语法→核心特性→实战入门”层层拆解,每个知识点落地到代码 ✅ 核心目标:小白不仅“懂概念”,更能“写得出、跑得起”,掌握Go语言入门核心能力 一、前置准备:先搞定环境和核心认知 1. Go语言是什么? Go(又称Golang)是谷歌2009年推出的编程语言,2026年已是云原生、高并发后端的首选语言——简单说: * 快:运行速度接近C/C++,编译速度秒杀Java; * 简单:语法比Java/Python更简洁,零基础3天能写业务代码; * 强:天生支持高并发,写直播、聊天、

By Ne0inhk
融合多模架构引领创新:2026年国产时序数据库全景解析与金仓实践

融合多模架构引领创新:2026年国产时序数据库全景解析与金仓实践

一、主流国产时序数据库概览 (2026) 国产时序数据库已形成多元产品矩阵,根据其核心技术路线、商业模式和市场定位,主要代表性产品如下: 数据库产品对比 TDengine * 核心厂商/社区: 涛思数据 * 主要特点与定位: 高性能、分布式,定位为AI驱动的工业大数据平台,在写入吞吐和存储成本方面优势显著,集群开源、生态开放。 KaiwuDB * 核心厂商/社区: 浪潮云弈 * 主要特点与定位: 强调分布式多模融合架构,支持时序、关系、文档等多种数据模型的统一处理,原生集成AI算法。 Apache IoTDB * 核心厂商/社区: 清华大学 (Apache基金会) * 主要特点与定位: 专为物联网设计,采用"端-边-云"协同原生架构,数据模型常采用树形结构贴合物理设备层级。 DolphinDB * 核心厂商/社区: 浙江智臾科技 * 主要特点与定位: 将数据库与强大的编程语言、流计算引擎融合,

By Ne0inhk