返回首页

03|SQL 增删改查入门

适用版本:MySQL 8.0.x

很多人学 MySQL 时,真正感兴趣的部分往往是“怎么把数据查出来”。这很正常,因为数据库最直接的存在感,往往就体现在一条条 SQL 上:页面列表能不能查到,用户信息能不能更新,订单数据能不能新增,错误记录能不能删掉。

而这些动作的核心,就是我们常说的 CRUD

  • Create:新增
  • Read:查询
  • Update:更新
  • Delete:删除

听起来很基础,但真正写好并不简单。很多线上事故、数据错乱、误删问题,并不是因为不会写 SQL,而是因为对增删改查的边界、条件、顺序和风险认识不够。

这篇文章会用一张简单示例表,带你从零走一遍最常见的 SQL 操作。重点不是“把语法背下来”,而是让你形成一个可靠习惯:任何写操作都要先想清楚影响范围,任何查询都要明确筛选条件与结果排序。


一、为什么增删改查是数据库入门的核心

如果说数据库与表操作是在“搭骨架”,那么增删改查就是“让骨架真正跑起来”。

1. 业务系统的日常动作,本质上就是增删改查

比如:

  • 用户注册,本质是新增一条用户记录
  • 用户列表,本质是查询一批记录
  • 用户修改昵称,本质是更新已有记录
  • 清理测试数据,本质是删除记录

所以你在业务里写的大量接口,最后都会落到 SQL 增删改查上。

2. 后续更复杂的 SQL,也都是在基础 CRUD 之上延伸

你后面会学到:

  • 聚合统计
  • 多表关联
  • 子查询
  • 事务控制
  • 索引优化

但无论多复杂,本质还是围绕“查什么、改什么、影响哪些数据”展开。

3. 基础写不好,后面越学越容易乱

很多初学者会遇到这些问题:

  • 更新语句不带条件,改了整张表
  • 删除语句条件写错,误删数据
  • 查询结果没排序,分页不稳定
  • 插入数据时列和值对不上

所以 CRUD 不只是“入门语法”,而是数据库操作安全感的来源。


二、先准备一张练习表

为了让后面的例子更连贯,我们先创建一张学生表。

CREATE TABLE students (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    student_no VARCHAR(20) NOT NULL,
    name VARCHAR(50) NOT NULL,
    age TINYINT NOT NULL,
    grade VARCHAR(20) NOT NULL,
    score DECIMAL(5,2) NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL
);

字段含义如下:

字段 含义
id 主键,自增
student_no 学号
name 姓名
age 年龄
grade 年级
score 成绩
status 状态,1 表示正常,0 表示禁用
created_at 创建时间
updated_at 更新时间

你可以把这张表理解成一张最小练习表,后面的 SQL 全围绕它展开。


三、新增数据:INSERT

新增是最先接触的写操作。它的作用很直接:往表里插入新记录。

1. 插入一条数据

INSERT INTO students (
    student_no,
    name,
    age,
    grade,
    score,
    status,
    created_at,
    updated_at
) VALUES (
    'S2026001',
    '张三',
    18,
    '高三',
    92.50,
    1,
    NOW(),
    NOW()
);

2. 为什么建议显式写列名

虽然你也可以写成:

INSERT INTO students VALUES (...);

但不推荐这样做。原因是:

  • 可读性差
  • 容易和列顺序耦合
  • 表结构变更后脚本更容易出错

更稳妥的做法,就是像上面那样明确写出列名。

3. 一次插入多条数据

INSERT INTO students (
    student_no,
    name,
    age,
    grade,
    score,
    status,
    created_at,
    updated_at
) VALUES
('S2026002', '李四', 17, '高二', 88.00, 1, NOW(), NOW()),
('S2026003', '王五', 18, '高三', 95.00, 1, NOW(), NOW()),
('S2026004', '赵六', 16, '高一', 76.50, 1, NOW(), NOW());

这种写法在导入小批量测试数据时非常常见。

4. 插入后立刻查询验证

SELECT id, student_no, name, age, grade, score
FROM students;

这一步非常重要。不要写完插入语句就直接认为“已经成功且数据正确”。


四、查询数据:SELECT

查询是最常用、也是最容易被低估的 SQL 操作。

1. 查询所有记录

SELECT id, student_no, name, age, grade, score, status
FROM students;

初学时最容易写:

SELECT * FROM students;

这在练习阶段没问题,但在正式业务中,通常更推荐明确写出需要的列。

2. 按条件查询

例如查询年级为高三的学生:

SELECT id, student_no, name, grade, score
FROM students
WHERE grade = '高三';

3. 多条件查询

查询高三且成绩大于等于 90 分的学生:

SELECT id, name, grade, score
FROM students
WHERE grade = '高三'
  AND score >= 90;

4. 查询部分列,而不是整行

SELECT name, score
FROM students
WHERE status = 1;

这类写法更符合真实业务需求,因为很多页面根本不需要整行所有字段。


五、条件过滤:WHERE 是查询与写操作的关键

WHERE 不只是查询时常用,更新和删除时也同样依赖它。

1. 常见比较写法

条件写法 含义
score = 90 分数等于 90
score > 90 分数大于 90
score >= 60 分数大于等于 60
grade <> '高一' 年级不等于高一
status = 1 状态为正常

示例:

SELECT id, name, score
FROM students
WHERE score < 80;

2. 使用 IN

查询高二和高三学生:

SELECT id, name, grade
FROM students
WHERE grade IN ('高二', '高三');

3. 使用 BETWEEN

查询分数在 80 到 90 之间的学生:

SELECT id, name, score
FROM students
WHERE score BETWEEN 80 AND 90;

注意:BETWEEN 是闭区间,包含边界值。

4. 处理空值时用 IS NULL

如果某个字段允许为空,判断时应写成:

WHERE some_column IS NULL

而不是:

WHERE some_column = NULL

这是 SQL 入门里很容易踩的坑。


六、排序与分页:别让查询结果“看起来随机”

很多人以为数据库返回结果天然有顺序,其实并不是。只有写了 ORDER BY,排序才是明确的。

1. 按成绩降序排序

SELECT id, name, score
FROM students
ORDER BY score DESC;

2. 先按年级,再按成绩排序

SELECT id, name, grade, score
FROM students
ORDER BY grade ASC, score DESC;

3. 只取前 3 条数据

SELECT id, name, score
FROM students
ORDER BY score DESC, id DESC
LIMIT 3;

4. 分页查询

例如每页 10 条,取第 2 页:

SELECT id, name, grade, score
FROM students
ORDER BY id DESC
LIMIT 10 OFFSET 10;

实践建议:分页时最好总是带明确排序,否则跨页结果可能不稳定。


七、更新数据:UPDATE

更新语句的语法不复杂,但风险往往比查询高得多。因为一旦条件不严谨,可能会改掉大量不该改的数据。

1. 更新一条记录

例如把张三的成绩改为 94:

UPDATE students
SET score = 94.00,
    updated_at = NOW()
WHERE student_no = 'S2026001';

2. 同时更新多个字段

UPDATE students
SET grade = '高三',
    status = 1,
    updated_at = NOW()
WHERE student_no = 'S2026002';

3. 更新前先用 SELECT 验证命中范围

这是非常重要的习惯。比如你准备执行:

UPDATE students
SET status = 0
WHERE score < 60;

在执行之前,先验证:

SELECT id, name, score, status
FROM students
WHERE score < 60;

这样你能明确知道哪些行将被影响。

4. 不带 WHERE 的更新非常危险

UPDATE students
SET status = 0;

这意味着整张表所有记录的 status 都会被改成 0。

除非你的目标就是全表更新,否则看到没有 WHEREUPDATE 时,一定要本能地警惕起来。


八、删除数据:DELETE

删除和更新一样,真正的难点不在语法,而在“你到底删了谁”。

1. 删除一条记录

DELETE FROM students
WHERE student_no = 'S2026004';

2. 按条件删除

例如删除状态为 0 的记录:

DELETE FROM students
WHERE status = 0;

3. 删除前先做确认查询

SELECT id, student_no, name, status
FROM students
WHERE status = 0;

先查清楚,再删除,是非常重要的安全习惯。

4. 不带 WHERE 的删除

DELETE FROM students;

这会删除整张表中的所有数据。

虽然表结构还在,但数据会被清空。学习阶段可以在练习表中尝试,正式环境必须非常谨慎。


九、一个完整示例:从新增到查询再到修改删除

下面给出一组完整练习,你可以按顺序执行。

步骤 1:插入几条数据

INSERT INTO students (
    student_no,
    name,
    age,
    grade,
    score,
    status,
    created_at,
    updated_at
) VALUES
('S2026101', '周明', 17, '高二', 81.00, 1, NOW(), NOW()),
('S2026102', '陈雨', 18, '高三', 93.50, 1, NOW(), NOW()),
('S2026103', '林杰', 16, '高一', 68.00, 1, NOW(), NOW());

步骤 2:查询全部数据

SELECT id, student_no, name, age, grade, score
FROM students
ORDER BY id ASC;

步骤 3:查询高三学生

SELECT id, name, grade, score
FROM students
WHERE grade = '高三';

步骤 4:把成绩低于 70 的学生标记为需关注

假设这里我们用 status = 0 表示需要关注:

先查:

SELECT id, name, score, status
FROM students
WHERE score < 70;

再改:

UPDATE students
SET status = 0,
    updated_at = NOW()
WHERE score < 70;

步骤 5:删除某条测试数据

DELETE FROM students
WHERE student_no = 'S2026103';

这一套流程基本就覆盖了 CRUD 的最小闭环。


十、关于受影响行数,要有基本意识

执行 INSERTUPDATEDELETE 后,客户端通常会返回受影响行数。

例如:

  • 1 row affected
  • 3 rows affected

这个信息很重要,因为它能帮助你判断:

  • 是否真的命中了目标数据
  • 条件是不是过宽了
  • 更新或删除是否比预期更多

特别是在写操作中,受影响行数往往是第一层预警信号。


十一、常见误区:CRUD 入门里最容易出错的地方

误区 1:新增时不写列名

短期看省事,长期看不稳定。表结构一变,脚本就容易出问题。

误区 2:查询时习惯性 SELECT *

练习可以,正式业务中应该尽量明确字段,避免返回不必要的数据。

误区 3:更新和删除不做条件确认

这是最危险的习惯之一。正确顺序通常应该是:

  1. 先写 SELECT 验证
  2. 再写 UPDATEDELETE
  3. 再核对受影响行数

误区 4:把 NULL 当普通值比较

判断空值必须用:

IS NULL
IS NOT NULL

误区 5:分页不加排序

没有 ORDER BY 的分页,本质上是不稳定的分页。今天看起来没问题,不代表明天还一样。


十二、实践建议:把 CRUD 写得更稳一点

1. 写操作前,先明确“影响范围”

问自己两个问题:

  1. 我准备影响哪些行?
  2. 我是怎么确认这些行正是目标数据的?

2. 把 WHERE 当成写操作的安全带

UPDATEDELETE 来说,WHERE 往往不是“附加条件”,而是安全边界。

3. 先小数据练习,再扩大范围

特别是学习阶段,先只插入 3 到 5 条测试数据,把每一步结果看清楚,比一上来导入几千条更有效。

4. 结果集展示时尽量明确排序

哪怕只是练习,也推荐写成:

ORDER BY id ASC

这样能帮助你建立稳定的结果预期。

5. 更新和删除前先复制一条同条件查询

这是一个很实用的习惯。比如:

SELECT * FROM students WHERE score < 60;
UPDATE students SET status = 0 WHERE score < 60;

这样可以明显降低误操作概率。


十三、小结

SQL 增删改查是 MySQL 最基础、也是最高频的能力。真正的重点不只是语法本身,而是你能不能建立对数据操作边界的清晰意识。

这篇文章主要讲了:

  • 什么是 CRUD,以及它为什么是数据库入门核心
  • 如何使用 INSERT 新增单条或多条记录
  • 如何通过 SELECT 做基本查询、条件过滤、排序和分页
  • 如何安全地使用 UPDATE 更新数据
  • 如何谨慎地使用 DELETE 删除数据
  • CRUD 操作中最容易踩的坑,以及更稳妥的实践建议

如果你把数据库操作比作开车,那么查询像是观察路况,新增像是上车,更新和删除则像是转向和刹车。真正让人出问题的,往往不是“不会开”,而是“没意识到自己会影响到什么”。把这个意识建立起来,后面学习多表查询、事务和索引时,就会稳很多。


📝 版权声明:本文为原创技术博客,转载请注明出处。

如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!

上一篇

02|数据库与表的基本操作

下一篇

04|数据类型与约束设计