DML常见操作

DML(Data Manipulation Language)数据操作语⾔,以INSERT、UPDATE、DELETE三种指 令为核⼼,分别代表插⼊、更新与删除,是必须要掌握的指令,DML和SQL中的select熟 称CRUD(增删改查)。

插⼊操作

MySQL INSERT 插入单行语法笔记

方式 1(最常用,推荐)

复制代码
insert into 表名[(字段,字段)] values (值,值);

规则说明

  1. 字段与值一一对应:数量相同、顺序匹配。
  2. 值的引号规则
    • 字符串 / 日期类型:值必须用单引号包裹
    • 数字类型:不需要单引号
  3. 非空字段 :定义为NOT NULL的字段,必须给值,不能省略。
  4. 可空字段 :两种写法
    • 不写这个字段,values 里也不写对应值
    • 写上字段,值写null
  5. 省略字段列表 :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查询出来的结果集,直接插入目标表。 ⚠️重点要求:

  1. select 返回的字段数量,要和前面 insert 指定的字段数量一致
  2. 顺序一一对应
  3. 数据类型匹配

示例:

复制代码
-- 将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 t
  • set:指定要修改的字段和新值,多个字段用逗号隔开
  • 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;

多表更新要点

  1. 在 update 后面列出需要更新的多张表,可以加别名
  2. where 里要写表关联条件,把多张表关联起来,否则会笛卡尔积,大量错误更新
  3. set 后面可以修改任意一张表的字段

MySQL DELETE 删除数据

单表删除语法

复制代码
delete [别名] from 表名 [as 别名] [where条件];

重点规则

  1. 给表起别名时:delete后面必须写别名
  2. 不起别名:delete后面的别名部分可以省略
  3. ⚠️ 不加 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)

  1. INSERT:新增行(单行、批量 values、insert-select 复制数据)
  2. UPDATE:修改已有行,不带 where 会全表更新
  3. DELETE:删除行,不带 where 会全表删除

共同红线:UPDATE 和 DELETE 执行前一定要确认where条件,防止误操作!

多表删除语法

语法

复制代码
delete [别名1,别名2] from 表1 [as 别名1],表2 [as 别名2] [where条件];

说明

  1. delete后面写要删除数据的表别名(可以写多个,代表同时删除多张表的数据)
  2. from后面列出所有需要关联查询的表,给表起别名
  3. where:写表之间的关联条件 + 过滤条件,不能省略,否则笛卡尔积,大量误删!
  4. 别名可以省略,直接写表名,多个表名逗号隔开

示例 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 两张表对应的行都会被删除。

多表删除核心要点

  1. delete后写哪个别名,就删哪张表;写多个别名就是多表一起删
  2. from 后面是关联用到的全部表
  3. where 必须写关联条件,否则会匹配所有行,造成大规模误删!
  4. 多表删除是 MySQL 特有语法,标准 SQL 不支持

增删改全套汇总(到目前为止所有知识点)

  1. INSERT:单行插入、批量 values 插入、insert...select 查询结果插入
  2. UPDATE:单表更新、多表更新,不带 where 会全表更新
  3. 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、外键限制。

相关推荐
lusklusklusk1 小时前
Oracle数据库基础之7_备份恢复基础之SCN
数据库·oracle
青山木2 小时前
秒杀系统设计(二):数据正确性——防超卖、分布式锁与一人一单
分布式·后端·mysql·中间件·架构
ao-weilai2 小时前
MySQL数据库:MySQL基础概要
数据库·mysql
雪碧聊技术2 小时前
从 0 跑通一个最小 RAG Demo:文档切分、向量检索与答案生成
数据库·oracle
喜欢的名字被抢了2 小时前
08-Redis 性能优化篇:快在哪、BigKey、HotKey、慢查询与内存
数据库·redis·性能优化
阳光九叶草LXGZXJ2 小时前
达梦数据库-学习-68-dmasm0X_XXXXXX.log日志激增
linux·运维·数据库·sql·学习
Mortalbreeze2 小时前
MySQL 基础篇(三):一文掌握 MySQL 常见数据类型
linux·服务器·数据库·mysql
青山木2 小时前
秒杀系统设计(一):需求拆解与流量治理
java·数据库·redis·后端·架构
lusklusklusk2 小时前
Oracle数据库基础之8_闪回
数据库·oracle