一、前言
- 回顾 DDL 与 DML 区别
- DDL:操作的对象:库、表结构
- 例如:增create/删drop/改alter/查show数据表、对数据表的操作(添加字段...)
-
- DML:操作的对象:表里面的数据
- 例如:增insert/删delete/改update/查select数据
- 前置说明:本篇所有 SQL 基于上一篇创建好的测试表,方便读者连贯复现 上篇博客链接:数据库和数据表的创建
- 重要提醒:UPDATE、DELETE 是高危语句,生产务必谨慎
二、INSERT 插入数据
INSERT [INTO] table_name
[(column [, column] ...)]
VALUES
(value_list) [, (value_list)] ...
value_list: value, [, value] ...
2.1 单行插入(指定字段)
指定要插入的数据的字段值,既可以指定一个字段,也可以指定多个字段,也可以指定全部字段。
示例 SQL
创建一个学生表(后续基于这个表操作)
CREATE table student (
id BIGINT,
name VARCHAR(15)
) ;
- 插入指定字段语句:
INSERT INTO student(name) VALUES('王五');
- 插入结果:

- SQL意义:插入一条name为'王五'的数据。
- 特点:只插入一条数据,字段顺序可随意调整,字段赋值可以省略,但要注意该字段前提为允许为空或有默认值(DEFAULT )
2.2 单行插入(省略字段列表)
该SQL语句虽省略了列表,但是在赋值的时候一定要和表字段的顺序一一对应,并且和字段数量一一匹配!
- 语法示例-指定字段列表顺序为id,name
INSERT INTO student(id,name) VALUES (2,'lisi');
- 插入结果:

- SQL意义:插入一条id为2,name为'lisi'的数据。
2.3 一次性多行插入(推荐写法)
- 特点:不再像上述的语句一般需要一条条插入数据,可以同时插入多条数据
- 语法示例-同时插入两条数据
INSERT INTO student(id,name) VALUES(3,'zhangsan'),(4,'zhaoqian');
- 插入结果:

- SQL意义:同时插入id为3,name为'zhangsan'和id为4,name为'zhoaqian'两条数据
- 优点:一次进行多条数据插入,减少网络 IO,插入性能优于多条单独一条数据的 insert
2.4 将查询结果插入表(INSERT ... SELECT)
查询库中其他表的数据或者本表的数据,将查询到的内容插入到该表中。
- 场景:适用于表之间数据迁移或进行复制
- 示例 SQL
INSERT INTO student(id,name) SELECT * from student where id =2;
- 插入结果:

- SQL意义:
查询student表中id为2的数据,并将其插入student中。

注意:如果查询的数据不存在,虽然结果不会报错,但数据不会被插入进去,因为该数据并不存在。
2.5 Insert 常见问题
- 主键重复报错
数据约束中,主键是唯一且非空的,是该表的唯一身份标识,若insert时主键的值在表中已存在,会因为身份标识重复而辨别不了数据的身份,所以会出错。
- 示例:
设置主键为id-注意字段为id的值不能为空也不能重复
ALTER TABLE `student` ADD CONSTRAINT pk_student_id PRIMARY KEY (id);
实验重复id

现在我们插入一个id为1的数据,查看结果

很明显,报错信息提示id为1已经有数据了,不能插入。
- 字段类型不匹配
字段有各自的类型,赋值时需一一对应,否则会报错。
示例:将字段为id的值设为'aa'(id 的类型为BIGINT)

明显的是,报错信息提示'aa'不符合id的类型。
值得注意的是:如果字段类型为varchar,如果输入的值为数字,mysql会进行隐型转换,会将数字转换成字符串的形式存储在字段中,varchar的本质其实就是字符串,所以不会报错。
- 非空字段没有赋值
NOT NULL字段不能为空!示例:
设置name字段为NOT NULL

插入id为11,name为空的数据

显而易见,name设为NOT NULL 的时候不能设置为NULL
重点:空字符串和NULL是不一样的,NOT NULL 只约束NULL,并不约束空字符串
NULL VS 空字符串:NOT NULL 表示未知,不确定性,空字符串表示一个空的字符串,有结果,是合法数据。
三、UPDATE 修改数据
3.1 基础语法
UPDATE LOW_PRIORITY IGNORE table_reference
SET assignment , *assignment* ...
WHERE *where_condition*
ORDER BY ...
LIMIT *row_count*
3.2 带 WHERE 条件更新
查询表中符合条件的数据进行修改
- 示例:修改id为5的数据,将name改成'小明'

UPDATE student SET name ='小明' WHERE id =5;
修改成功!
3.3 ⚠️重点大坑
没有对修改数据这一行为设置where条件查询,则会进行全表的修改,一般很少会进行全表的修改,在修改时要注意是否需要查询条件。
生产规范:执行 update 前先用 select 校验 where 条件是否正确
3.4 同时更新多个字段
更新操作可以进行多个字段的修改,示例:将id为5,name为'小明'修改为id为13,name为'小张'
UPDATE student SET id=13,name ='小张' WHERE id =5;

修改成功!
3.5 UPDATE 常见坑总结
1、使用where条件进行更新操作,要保证该条件有符合的数据,否则就会更新失败而报错。
2、和insert语句一样,如果修改的字段为主键,需要注意不能和其他字段重复(一般不会去更新主键字段)
四、DELETE 删除数据
4.1 DELETE 基础语法(带 WHERE)
DELETE FROM tbl_name WHERE *where_condition* ORDER BY ... LIMIT *row_count*
- 示例:删除id为5的数据
DELETE from student WHERE id=5;

4.2 ⚠️重点
进行DELETE操作时,必须带有where条件查询,否则就会将整个表的数据全部删除,在实际业务中,这是一个非常可怕的事情!
4.3 DELETE VS TRUNCATE 对比(面试高频)
| 对比项 | DELETE | TRUNCATE |
|---|---|---|
| 作用 | 删除表中数据,保留表结构 | 清空全表数据,保留表结构 |
| 日志 | 记录日志,可以事务回滚 | 不记录日志,无法回滚 |
| 自增主键 | 自增序号继续往下走 | 重置自增主键 |
| 触发触发器 | 会触发 | 不会触发 |
| DML/DDL | DML | DDL |
注意:TRUNCATE 不是 DML,属于 DDL
五、实操小技巧与生产规范
- 写 UPDATE/DELETE,先写 WHERE,先用 SELECT 验证查询结果,再改 delete/update
- 生产环境关闭自动提交,事务包裹,确认无误再 commit
- 禁止线上直接执行不带 where 的 update、delete
- 重要数据删除前先备份
六、总结
- INSERT:新增记录;UPDATE:修改已有记录;DELETE:删除记录
- DML 操作的核心安全点:WHERE 条件
- 预告下一篇:MySQL DQL 单表查询(SELECT)