DML(Data Manipulation Language)数据操作语⾔,以INSERT、UPDATE、DELETE三种指 令为核⼼,分别代表插⼊、更新与删除,是必须要掌握的指令,DML和SQL中的select熟 称CRUD(增删改查)。
插⼊操作
MySQL INSERT 插入单行语法笔记
方式 1(最常用,推荐)
insert into 表名[(字段,字段)] values (值,值);
规则说明
- 字段与值一一对应:数量相同、顺序匹配。
- 值的引号规则
- 字符串 / 日期类型:值必须用单引号包裹
- 数字类型:不需要单引号
- 非空字段 :定义为
NOT NULL的字段,必须给值,不能省略。 - 可空字段 :两种写法
- 不写这个字段,values 里也不写对应值
- 写上字段,值写
null
- 省略字段列表 :
insert into 表名 values(值1,值2),代表给全部字段插入,值顺序必须和建表时字段顺序完全一致。
示例:
-- 指定字段插入
insert into student(name,age) values('张三',18);
-- 全字段插入(不能少值)
insert into student values(1,'张三',18,'2025-01-01');
方式 2(MySQL 特有,不常用)
insert into 表名 set 字段 = 值,字段 = 值;
特点:适合少量字段插入,标准 SQL 不支持,其他数据库不一定兼容,开发优先用方式 1。
示例:
insert into student set name='李四',age=20;
补充小知识点
-
插入多条:
values后面可以写多组括号,逗号隔开insert into student(name,age) values ('a',10),('b',11);
MySQL 批量插入 两种方式
方式 1:一次性写多条values(最常用)
insert into 表名 [(字段,字段)] values (值,值),(值,值),(值,值);
原理:多个行数据用逗号分隔,一次性插入多条记录。
示例:
-- 向student表批量插入3条数据,只指定name、age字段
insert into student(name,age) values
('张三',18),
('李四',19),
('王五',20);
✅优点:简洁,一次网络请求,效率高。
方式 2:insert ... select 从别的表查询并插入
insert into 表 [(字段,字段)]
select 语句;
含义:把
select查询出来的结果集,直接插入目标表。 ⚠️重点要求:
- select 返回的字段数量,要和前面 insert 指定的字段数量一致
- 顺序一一对应
- 数据类型匹配
示例:
-- 将student_backup表里面年龄大于18的数据,复制插入student表
insert into student(name,age)
select name,age from student_backup where age>18;
适用场景:表之间数据迁移、复制数据,不需要手动写值。
对比小结
表格
| 方式 | 适用场景 |
|---|---|
| values 多组括号 | 新增少量固定数据,写死的值 |
| insert ... select | 从其他表查询,批量迁移复制数据 |
补充:和上一张单行 insert 联动记忆
- 单行:
insert into 表(字段) values(值)- 批量 values:
insert into 表(字段) values(值),(值),(值)- 批量查询导入:
insert into 表(字段) select ...
MySQL UPDATE 更新(单表 + 多表更新)
一、单表更新(重点)
语法
update 表名 [as 别名] set [别名.]字段 = 值,[别名.]字段 = 值 [where条件];
as:给表起别名,as可以省略,test1 t等价test1 as tset:指定要修改的字段和新值,多个字段用逗号隔开where:限定要修改哪些行,开发必须写!不带 where 会更新整张表,风险极高
示例解析
-- 给test1起别名t,所有行a字段更新为2(无where,全表更新)
update test1 t set t.a = 2;
返回结果说明: Rows matched:6 → 语句匹配到 6 条记录 Changed:4 → 只有 4 条记录的值真正发生变化(原本 a=2 的数据不会改动)
-- 显式写as别名,全表更新a=3
update test1 as t set t.a = 3;
-- 同时更新多个字段,a改成1,b改成2
update test1 set a = 1,b=2;
✅ 推荐带 where 的真实开发写法:
-- 只修改id=5这一行,修改name和age
update student set name='小红',age=22 where id = 5;
二、多表更新
作用:一条 update 语句同时修改多张关联表的数据
语法
update 表1 [as 别名1],表2 [as 别名2]
set 别名1.字段=值,别名2.字段=值
where 关联条件 [过滤条件];
示例: student 学生表,score 成绩表,两表通过student.id = score.stu_id关联
-- 学生id=1的姓名改为小明,同时他的语文成绩改为95
update student s, score sc
set s.name='小明', sc.chinese=95
where s.id = sc.stu_id and s.id = 1;
多表更新要点
- 在 update 后面列出需要更新的多张表,可以加别名
- where 里要写表关联条件,把多张表关联起来,否则会笛卡尔积,大量错误更新
- set 后面可以修改任意一张表的字段
MySQL DELETE 删除数据
单表删除语法
delete [别名] from 表名 [as 别名] [where条件];
重点规则
- 给表起别名时:
delete后面必须写别名 - 不起别名:
delete后面的别名部分可以省略 - ⚠️ 不加 where:删除整张表全部数据!生产环境极度危险!
示例
-- 写法1:无别名,删除test1表全部记录
delete from test1;
-- 写法2:写别名,删除test1表全部记录
delete test1 from test1;
✅ 带 where(工作最常用,只删符合条件的数据)
-- 删除id=10的这一行
delete from test1 where id = 10;
-- 使用别名写法,删除age>30的数据
delete t from test1 as t where t.age > 30;
拓展补充(常考点:DELETE vs TRUNCATE)
表格
| DELETE | TRUNCATE | |
|---|---|---|
| 作用 | 删除表部分 / 全部行 | 清空整张表所有数据 |
| where | ✅ 支持 where 条件 | ❌ 不支持 where |
| 事务 | 可以回滚 | 不能回滚(DDL) |
| 自增主键 | 继续递增 | 自增主键重置从 1 开始 |
| 日志 | 记录日志,慢 | 不记录单行日志,速度快 |
一句话区分:想删指定行用
delete;要清空全表、不考虑事务回滚,才用truncate。
增删改小结(INSERT / UPDATE / DELETE)
- INSERT:新增行(单行、批量 values、insert-select 复制数据)
- UPDATE:修改已有行,不带 where 会全表更新
- DELETE:删除行,不带 where 会全表删除
共同红线:
UPDATE和DELETE执行前一定要确认where条件,防止误操作!
多表删除语法
语法
delete [别名1,别名2] from 表1 [as 别名1],表2 [as 别名2] [where条件];
说明
delete后面写要删除数据的表别名(可以写多个,代表同时删除多张表的数据)from后面列出所有需要关联查询的表,给表起别名where:写表之间的关联条件 + 过滤条件,不能省略,否则笛卡尔积,大量误删!- 别名可以省略,直接写表名,多个表名逗号隔开
示例 1
delete t1 from test1 t1,test2 t2 where t1.a=t2.c2;
含义: 只删除test1(t1)表里的数据;删除条件:test1.a的值和test2.c2的值相等。
test2 表的数据不会被删除,只是拿 test2 做关联判断筛选 test1 要删的行。
完整测试脚本(图下方建表语句)
-- 如果表存在就删除
drop table if exists test1;
-- 创建test1
create table test1(a int,b int);
drop table if exists test2;
create table test2(c1 int,c2 int,c3 int);
-- 可以自己插入测试数据测试
insert into test1(a,b) values (1,10),(2,20),(3,30);
insert into test2(c1,c2,c3) values (100,2,200),(101,5,201);
-- 执行删除:删除test1中a等于test2.c2的行,这里会删掉test1里a=2那一行
delete t1 from test1 t1,test2 t2 where t1.a=t2.c2;
拓展:同时删除两张表的数据
如果想同时删掉 test1 和 test2 满足条件的记录 ,delete后面写两个别名:
delete t1,t2 from test1 t1,test2 t2 where t1.a=t2.c2;
满足关联条件的数据,test1 和 test2 两张表对应的行都会被删除。
多表删除核心要点
delete后写哪个别名,就删哪张表;写多个别名就是多表一起删- from 后面是关联用到的全部表
- where 必须写关联条件,否则会匹配所有行,造成大规模误删!
- 多表删除是 MySQL 特有语法,标准 SQL 不支持
增删改全套汇总(到目前为止所有知识点)
- INSERT:单行插入、批量 values 插入、insert...select 查询结果插入
- UPDATE:单表更新、多表更新,不带 where 会全表更新
- DELETE:单表删除、多表删除,不带 where 会全表删除
考试 / 面试高频坑:update、delete 操作,忘记 where 条件 → 全表改动,重大事故。
truncate 以及 drop /truncate/delete 三者对比
truncate 语法
truncate 表名;
作用:清空整张表所有数据,保留表结构(字段、约束、索引都还在) ⚠️ 不能加
where,无法只删除部分行;一执行就清空全部数据。
三者核心区别(重点考点)
1. drop table
drop table 表名;
删除表结构 + 全部数据,释放存储空间。
- 表直接消失,字段、约束、索引、触发器全部删掉
- 依赖该表的存储过程 / 函数会保留,但状态失效(invalid)
- 之后想使用,必须重新建表
2. truncate
truncate 表名;
只删所有数据,保留表结构定义。
- 不支持 where,不能删除部分行
- 自增主键重置为初始值
- DDL 语句,不记录单行事务日志,不能回滚
- 速度远快于不带 where 的 delete
- 有外键
foreign key引用的表,不能直接 truncate
3. delete
delete from 表名 [where 条件];
删除表中的行数据,表结构完全保留
- ✅支持 where,可以只删除符合条件的部分行;不加 where 会删除全部行
- DML 语句,删除会记录事务日志,可以事务回滚
- 自增主键不会重置,继续接着之前数值增长
- 逐行删除,删除大量数据时速度慢
精简对比表
| 特性 | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| 是否删除表结构 | ❌保留 | ❌保留 | ✅删除整张表 |
| where 条件 | ✅支持 | ❌不支持 | ❌不支持 |
| 事务回滚 | ✅可以回滚 | ❌不可回滚 | ❌不可回滚 |
| 自增主键 | 不重置 | 重置 | 表不存在 |
| 删除原理 | 逐行删除,记日志 | 直接释放数据页 | 删除表定义 + 数据 |
| 执行速度 | 最慢 | 很快 | 最快 |
| 外键约束 | 可以正常使用 | 有外键引用时不能 truncate | 有外键依赖不能 drop |
一句话记忆
DELETE:删行,可加条件,可回滚TRUNCATE:清空全表数据,表还在,不能回滚DROP:表直接删掉,结构数据全部消失
面试常问:
truncate和delete from 表名;有什么区别? 答要点:事务回滚、自增主键、日志记录、是否支持 where、外键限制。