Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL DML 操作

MySQL DML 操作(CRUD)总结

作者:峥无

本文全面讲解 MySQL 核心的 CRUD 增删改查操作,是数据库入门必备教程,结合实战案例详解 INSERT 插入、SELECT 查询、UPDATE 修改、DELETE 删除四大核心语句,下面就来详细的介绍一下

本文基于 MySQL 8.0 编写,全面讲解数据表增(Create)、查(Retrieve)、改(Update)、删(Delete) 核心语法、实战案例、易错点、执行顺序。

一、前言:什么是 CRUD

数据库最核心的四大操作简称 CRUD,对应日常数据管理所有场景:

英文中文对应 SQL 操作
Create新增数据INSERT
Retrieve查询数据SELECT(使用频率最高)
Update修改数据UPDATE
Delete删除数据DELETE / TRUNCATE

前置准备:本文所有案例统一使用两张测试表,先执行建表语句,后续案例均基于此表操作。

-- 学生表:存储学生基础信息
CREATE TABLE students (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID,自增',
    sn INT NOT NULL UNIQUE COMMENT '学号,唯一约束',
    name VARCHAR(20) NOT NULL COMMENT '姓名',
    qq VARCHAR(20) COMMENT 'QQ号,允许为空'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 成绩表:存储学生考试成绩(核心查询案例表)
CREATE TABLE exam_result (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
    name VARCHAR(20) NOT NULL COMMENT '学生姓名',
    chinese FLOAT DEFAULT 0.0 COMMENT '语文成绩',
    math FLOAT DEFAULT 0.0 COMMENT '数学成绩',
    english FLOAT DEFAULT 0.0 COMMENT '英语成绩'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 给成绩表插入测试数据
INSERT INTO exam_result (name, chinese, math, english)
VALUES 
('张三', 67, 98, 56),
('李四', 87, 78, 77),
('王五', 88, 98, 90),
('赵六', 82, 84, 67),
('钱七', 55, 85, 45),
('孙八', 70, 73, 78),
('周九', 75, 65, 30);

二、数据新增:INSERT(Create)

2.1 基础语法

-- 标准语法,INTO 可省略
INSERT [INTO] 表名 
[(字段1, 字段2, ...)] 
VALUES (值1, 值2, ...), (值1, 值2, ...);

规则:

  1. 字段列表 和 VALUES 值列表 数量、顺序、数据类型必须一一对应
  2. 自增主键、默认值字段可省略不写,MySQL 自动填充;
  3. 支持单行插入多行批量插入(多行插入效率远高于多次单行插入)。

2.2 分类实战案例

2.2.1 全列插入(不指定字段)

不写字段列表,代表给表中所有字段按顺序赋值,自增主键也需要手动指定值。

-- 单行全列插入
INSERT INTO students VALUES (1, 1001, '张三', '123456');
-- 多行全列插入
INSERT INTO students VALUES 
(2, 1002, '李四', '654321'),
(3, 1003, '王五', NULL); -- QQ为空,使用 NULL

2.2.2 指定列插入(推荐用法)

只给部分字段赋值,未指定字段会使用默认值/自增规则,日常开发最常用。

-- 仅插入学号、姓名,id自增、qq默认为NULL
INSERT INTO students (sn, name) 
VALUES (1004, '赵六'), (1005, '钱七');

2.2.3 插入冲突处理(主键/唯一键重复)

主键(PRIMARY KEY)唯一键(UNIQUE) 重复时,直接插入会报错 Duplicate entry,MySQL 提供两种解决方案。

方案1:存在则更新ON DUPLICATE KEY UPDATE

逻辑:键重复时,更新指定字段;无重复则正常插入。

-- id=1 已存在,触发更新;不存在则新增
INSERT INTO students (id, sn, name) 
VALUES (1, 1009, '小张')
ON DUPLICATE KEY UPDATE sn = 1009, name = '小张';

返回行数说明(易错点)

方案2:存在则替换REPLACE INTO

逻辑:键重复时,先删除原数据,再插入新数据;无重复则直接插入。

-- 学号sn是唯一键,重复则删除旧数据、插入新数据
REPLACE INTO students (sn, name, qq) VALUES (1001, '新张三', '999999');

区别总结

2.3 拓展:插入查询结果

一张表的查询结果直接插入另一张表,常用于数据备份、去重、数据迁移。

-- 语法:INSERT ... SELECT
INSERT INTO 目标表(字段1,字段2) SELECT 字段1,字段2 FROM 源表 [条件];

-- 示例:将成绩表中数学>80的学生姓名、成绩插入新表
CREATE TABLE temp_result (name VARCHAR(20), math FLOAT);
INSERT INTO temp_result (name, math) 
SELECT name, math FROM exam_result WHERE math > 80;

三、数据查询:SELECT(Retrieve)【重点】

SELECT 是 MySQL 使用率最高的语句,支持字段筛选、条件过滤、排序、分页、聚合、分组等功能。

3.1 完整语法框架

SELECT [DISTINCT] 字段列表
FROM 表名
[WHERE 条件]          -- 行过滤
[GROUP BY 分组字段]   -- 分组
[HAVING 分组后条件]   -- 分组过滤
[ORDER BY 排序字段]   -- 结果排序
[LIMIT 分页限制];     -- 分页

3.2 基础查询

3.2.1 全列查询*

* 代表查询表中所有字段

SELECT * FROM exam_result;

⚠️ 开发易错点
禁止在生产环境随意使用 SELECT *

  1. 传输大量无用数据,影响性能;
  2. 无法使用索引,查询效率降低;
  3. 表结构变更后,查询结果列会错乱。

3.2.2 指定列查询(推荐)

手动指定需要查询的字段,字段顺序可自定义,和表结构顺序无关。

-- 只查询姓名、语文、数学成绩
SELECT name, chinese, math FROM exam_result;

3.2.3 查询表达式 & 字段别名

查询列可以是算术表达式(加减乘除),使用 AS 给列起别名(AS 可省略)。

-- 1. 计算总分,并设置别名 总分
SELECT 
    name,
    chinese,
    math,
    english,
    chinese + math + english AS total_score -- 别名
FROM exam_result;

-- 2. AS 可省略,简写形式
SELECT name, chinese + math + english total FROM exam_result;

⚠️ 易错点WHERE 子句不能使用字段别名(执行顺序问题),ORDER BY 可以使用别名。

3.2.4 结果去重DISTINCT

去除查询结果中完全重复的行,写在 SELECT 之后。

-- 查询所有不重复的数学成绩
SELECT DISTINCT math FROM exam_result;

3.3 条件过滤:WHERE 子句

WHERE 用于筛选符合条件的行,支持比较运算符、逻辑运算符、模糊查询、空值判断

3.3.1 常用运算符汇总

1)比较运算符

运算符作用备注
> >= < <=大小比较常规数值判断
=等于对 NULL 无效,NULL = NULL 结果仍为 NULL
<=>安全等于支持 NULL 比较,NULL <=> NULL 结果为真
!= / <>不等于两种写法等价
BETWEEN a AND b区间匹配闭区间 [a,b],包含两端值
IN(值1,值2...)枚举匹配匹配括号内任意一个值

2)空值判断

MySQL 中 NULL 不等于任何值,必须使用专用关键字

3)逻辑运算符

4)模糊查询LIKE

搭配通配符使用,常用于搜索场景:

3.3.2 实战案例

-- 1. 英语成绩低于60分的学生(比较运算)
SELECT name, english FROM exam_result WHERE english < 60;

-- 2. 语文成绩在 [80,90] 区间(两种写法等价)
SELECT name, chinese FROM exam_result WHERE chinese >=80 AND chinese <=90;
SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;

-- 3. 数学成绩为 78、84、98 之一(IN 枚举)
SELECT name, math FROM exam_result WHERE math IN(78,84,98);

-- 4. 模糊查询:姓"张"的学生(% 通配)
SELECT name FROM exam_result WHERE name LIKE '张%';
-- 名字第二个字为"五"(_ 单个字符)
SELECT name FROM exam_result WHERE name LIKE '_五';

-- 5. 判断空值:查询QQ号为空的学生
SELECT name FROM students WHERE qq IS NULL;

-- 6. 多条件组合:语文>80 并且 不姓王
SELECT name, chinese FROM exam_result 
WHERE chinese > 80 AND NOT name LIKE '王%';

3.4 结果排序:ORDER BY

对查询结果排序,默认升序(ASC)
语法:ORDER BY 字段 [ASC|DESC]

3.4.1 单字段排序

-- 数学成绩升序(默认ASC)
SELECT name, math FROM exam_result ORDER BY math;
-- 数学成绩降序
SELECT name, math FROM exam_result ORDER BY math DESC;

3.4.2 多字段排序(优先级从左到右)

先按第一个字段排序,值相同时再按第二个字段排序。

-- 先数学降序,数学相同则英语升序
SELECT name, math, english FROM exam_result
ORDER BY math DESC, english ASC;

3.4.3 排序规则补充(易错点)

  1. NULL 在排序中视为最小值:升序时 NULL 排在最前,降序时排在最后;
  2. ORDER BY 支持表达式、字段别名
  3. ORDER BY 时,查询结果顺序无定义,不要依赖默认顺序。

3.5 分页查询:LIMIT

分页是项目必备功能,用于限制返回数据行数,语法两种写法:

-- 写法1:LIMIT 行数 (从第0条开始,取N条)
SELECT 字段 FROM 表 LIMIT N;

-- 写法2:LIMIT 偏移量, 行数 (偏移量从0开始)
SELECT 字段 FROM 表 LIMIT offset, N;

-- 写法3(推荐,语义清晰):LIMIT 行数 OFFSET 偏移量
SELECT 字段 FROM 表 LIMIT N OFFSET offset;

分页实战(每页3条数据)

-- 第1页:偏移0,取3条
SELECT * FROM exam_result ORDER BY id LIMIT 3 OFFSET 0;
-- 第2页:偏移3,取3条
SELECT * FROM exam_result ORDER BY id LIMIT 3 OFFSET 3;
-- 第3页:偏移6,取3条(不足3条则返回剩余数据)
SELECT * FROM exam_result ORDER BY id LIMIT 3 OFFSET 6;

开发建议:查询未知大表时,强制加 LIMIT 1,避免全表查询导致数据库卡死。

3.6 聚合函数

聚合函数用于统计计算,作用于一组数据,返回一个结果。常用 5 大聚合函数:

函数作用特性
COUNT(字段/*)统计行数COUNT(*) 统计所有行;COUNT(字段) 忽略 NULL
SUM(字段)求和仅对数值有效,无数据返回 NULL
AVG(字段)求平均值忽略 NULL
MAX(字段)求最大值支持数值、字符串
MIN(字段)求最小值支持数值、字符串

聚合函数案例

-- 1. 统计总人数(COUNT(*) 统计所有行)
SELECT COUNT(*) AS total_student FROM exam_result;

-- 2. 统计有QQ号的学生数(COUNT(字段) 忽略NULL)
SELECT COUNT(qq) AS have_qq FROM students;

-- 3. 数学成绩总分、平均分
SELECT SUM(math) AS math_sum, AVG(math) AS math_avg FROM exam_result;

-- 4. 英语最高分、最低分
SELECT MAX(english) AS max_en, MIN(english) AS min_en FROM exam_result;

-- 5. 去重统计:不重复的数学成绩数量
SELECT COUNT(DISTINCT math) FROM exam_result;

3.7 分组查询:GROUP BY + HAVING

GROUP BY:按照指定字段分组,配合聚合函数做分组统计;
HAVING:对分组后的结果再次过滤(区别于 WHERE)。

核心区别(高频面试题)

  1. WHERE分组前过滤原始数据,不能使用聚合函数;
  2. HAVING分组后过滤分组结果,可以使用聚合函数。

分组案例

-- 模拟场景:新增班级字段,按班级分组统计
ALTER TABLE exam_result ADD class VARCHAR(10) COMMENT '班级';
UPDATE exam_result SET class = '一班' WHERE id <=4;
UPDATE exam_result SET class = '二班' WHERE id >4;

-- 1. 按班级分组,统计每个班级人数、语文平均分
SELECT class, COUNT(*) AS num, AVG(chinese) AS avg_ch
FROM exam_result
GROUP BY class;

-- 2. 分组后过滤:只显示平均分大于70的班级(HAVING)
SELECT class, AVG(chinese) AS avg_ch
FROM exam_result
GROUP BY class
HAVING avg_ch > 70;

四、数据修改:UPDATE

4.1 基础语法

UPDATE 表名 
SET 字段1 = 值1, 字段2 = 值2, ...
[WHERE 条件] 
[ORDER BY 排序]
[LIMIT 行数];

⚠️ 高危警告:省略 WHERE 会更新全表所有数据,生产环境严禁裸写 UPDATE 表名 SET ...!

4.2 实战案例

-- 1. 单字段更新:将张三的数学成绩改为80
UPDATE exam_result SET math = 80 WHERE name = '张三';

-- 2. 多字段更新:同时修改语文、英语成绩
UPDATE exam_result 
SET chinese = 70, english = 60 
WHERE name = '李四';

-- 3. 基于原数据更新(字段自增/自减)
UPDATE exam_result SET math = math + 10 WHERE math < 80;

-- 4. 结合排序+分页更新:成绩倒数3名,数学+20分
UPDATE exam_result 
SET math = math + 20
ORDER BY chinese + math + english ASC
LIMIT 3;

五、数据删除:DELETE & TRUNCATE

5.1 DELETE 语句(删除行数据)

5.1.1 基础语法

-- 删除符合条件的行
DELETE FROM 表名 [WHERE 条件] [LIMIT 行数];

案例

-- 1. 删除指定学生数据(推荐,带WHERE)
DELETE FROM exam_result WHERE name = '李四';

-- 2. 删除全表数据(高危!)
DELETE FROM students;

DELETE 特性

  1. 只删除数据,保留表结构;
  2. 支持事务,可以回滚;
  3. 自增主键 AUTO_INCREMENT 不会重置,再次插入会延续之前的ID。

5.2 TRUNCATE 语句(截断表)

语法

TRUNCATE [TABLE] 表名;

TRUNCATE 特性(和 DELETE 核心区别,面试重点)

  1. 只能清空整张表,无法按条件删除单行;
  2. 不触发事务、无法回滚,执行速度远快于 DELETE
  3. 清空后重置自增主键,新数据ID从1重新开始;
  4. 属于 DDL 语句(数据定义),DELETE 属于 DML 语句(数据操作)。

适用场景

仅用于整表数据清空(测试环境、数据初始化),生产环境谨慎使用。

5.3 DELETE vs TRUNCATE 对比表

特性DELETETRUNCATE
操作范围可按条件删除单行/多行只能清空全表
事务支持支持事务、可回滚不支持事务、不可回滚
自增ID不重置重置为初始值
执行速度较慢极快
语句类型DML(数据操作)DDL(数据定义)

六、高频考点:SQL 关键字执行顺序(面试必背)

完整执行顺序(从先到后):

FROM → ON → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT

顺序解读(解释易错点)

  1. 先通过 FROM 找到表,WHERE 过滤原始数据;
  2. GROUP BY 分组,HAVING 过滤分组结果;
  3. 再执行 SELECT 生成字段别名 → 去重 DISTINCT;
  4. 最后 ORDER BY 排序、LIMIT 分页。

对应易错点解释:

七、全局易错点总结(避坑指南)

  1. NULL 相关:= NULL 永远查不到数据,必须用 IS NULL / IS NOT NULL;NULL <=> NULL 才会判定为真。
  2. 全表操作:UPDATE、DELETE 不加 WHERE 会操作全表,生产环境禁止使用。
  3. 别名使用:WHERE 不能用字段别名,ORDER BY/HAVING 可以。
  4. DISTINCT:针对整行去重,不是单个字段。
  5. LIMIT 偏移量:偏移量从 0 开始,分页公式:偏移量 = (页码 - 1) * 每页条数。
  6. TRUNCATE:不可逆、不支持事务,正式环境严禁随意执行。
  7. INSERT 多行:优先使用多行 VALUES 批量插入,性能远高于多次单行插入。

八、总结

本文覆盖 MySQL CRUD 全部核心语法、实战案例、易错点、面试考点,是 MySQL 入门的核心内容:

  1. 新增:INSERT 分单行/多行、指定列/全列,冲突处理用 ON DUPLICATE KEY / REPLACE;
  2. 查询:SELECT 是核心,掌握条件、排序、分页、聚合、分组五大功能;
  3. 修改:UPDATE 务必加 WHERE,避免全表更新;
  4. 删除:区分 DELETE(灵活、可回滚)和 TRUNCATE(极速、清空全表);
  5. 执行顺序:理解关键字执行顺序,就能规避 90% 的语法报错。

到此这篇关于MySQL DML 操作(CRUD)总结的文章就介绍到这了,更多相关MySQL DML 操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文