增删改查这四件事,可能是大多数人和 MySQL 打交道的第一步。我刚入行那会儿也觉得,CRUD 嘛,背几条 SQL 语法就能上手,能有多难?可真到生产环境里跑过几年之后才发现,同样是写INSERT、SELECT、UPDATE、DELETE,有人写出来的东西在几十万数据量下照样秒回,有人写出来的东西在几千条数据时就能把数据库拖垮。差别不在语法,而在对数据操作底层逻辑的理解。这篇东西我就从实战角度,把 MySQL 增删改查里值得琢磨的细节、容易踩的坑、还有我个人的操作习惯一次性捋清楚,希望能帮你少走点弯路。
1. 增删改查的本质:别把 CRUD 只当成四句语法
很多人学 MySQL 增删改查,是从背语句开始的:INSERT INTO搞定写入,SELECT搞定查询,UPDATE搞定修改,DELETE搞定删除。语法本身确实不难,难的是理解这四类操作在数据库内部到底做了什么,以及它们之间怎么互相影响。
1.1 为什么说 CRUD 是所有业务系统的地基
你可以把任何一套业务系统想象成一个记账本:用户注册是增,用户登录是查,用户改头像昵称是改,用户注销是删。所有互联网产品的核心功能,归根到底都是这四类操作的组合。正因如此,CRUD 的性能、稳定性和安全性,几乎决定了整个业务系统的上限。
我跟很多刚入门的朋友交流时发现一个普遍现象:大家觉得增删改查太简单,不值得花心思研究。但实际上,生产环境里的 CRUD 和教科书上的 CRUD 完全不是一回事。教科书教你的是"怎么写能跑通",生产环境要求的是"怎么写才能扛住并发、不走全表扫描、不锁住整张表、不出脏数据"。举个例子,同样是插入一万条数据,一条条循环INSERT可能要几秒钟,而用批量插入的方式可能只要几十毫秒。绝大多数初学者不会意识到这种差异,但在真实项目中,这种差异就是线上事故和正常运行的差别。
1.2 数据结构设计决定了 CRUD 的复杂度上限
还有一个更隐蔽的因素:增删改查好不好写、性能好不好,很大程度在表结构设计阶段就定下来了。
有一句话叫"三流程序员写代码,一流程序员设计表"。如果你的表设计不合理,比如该建索引的字段没建、字段类型选得过大、表之间关系混乱,那后面的所有SELECT查询都会变得拧巴,所有UPDATE和DELETE都会变得危险。反过来说,一张设计良好的表,能让增删改查的业务逻辑非常简洁。
以用户表为例,我见过不少新手拿VARCHAR(255)存用户ID、拿TEXT存手机号,这种类型选型会导致两个问题:一是存储空间浪费,索引体积变大,查询变慢;二是语义不清晰,索引长度太长,联合索引根本没法设计。正确做法是能用INT或BIGINT的绝不用字符串,能用CHAR的不要用VARCHAR,能用DATETIME的不要用字符串存时间。表结构设计是 CRUD 的地基,地基歪了,上面写多少优化技巧都白搭。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. INSERT 插入数据:批量插入与并发写入的正确姿势
插入操作看起来最简单,就是把数据写进去,但恰恰是很多性能问题的源头。我在实际项目中处理过几次写入慢的问题,最后发现根子都出在插入方式上。
2.1 单条插入与批量插入的性能差距
先看一个最典型的场景:往一张表里插入一万条数据。新手最常见的写法是在代码里循环一万次,每次都执行一句:
sql复制INSERT INTO user (name, age, city) VALUES ('张三', 25, '北京');
这种方式每执行一次,MySQL 都要做一次 SQL 解析、权限检查、事务处理,还要同步一次日志,开销非常大。实测下来,在普通配置的机器上,循环插入一万条可能需要几秒甚至十几秒。
而换成批量插入:
sql复制INSERT INTO user (name, age, city) VALUES
('张三', 25, '北京'),
('李四', 30, '上海'),
('王五', 28, '广州');
一次把多条记录拼在同一个INSERT语句里,MySQL 只需要解析一次 SQL,日志写入也只需要同步一次。同样是插入一万条,耗时往往能缩短到原来的十分之一甚至更低。我在一个数据迁移项目里,就是把百万级数据的逐条插入改成每 500 条一批的批量插入,整体耗时从四十多分钟降到了三分钟以内,效果立竿见影。
提示:批量插入也不是越大越好。一次插入 500 到 1000 条是实践下来比较稳妥的范围。如果单条
VALUES数量太多,SQL 语句会变得很长,占用内存增加,还可能导致主从复制的延迟增大。要根据实际场景找到适合自己的批量大小。
2.2 INSERT 与事务的配合:要么全成功,要么全失败
如果你往多张表里插入数据,比如注册一个用户,既要写用户表,又要写用户的扩展信息表,那这两条插入操作必须放在同一个
