一、先搞清楚:DML 是干什么的?
DML(Data Manipulation Language,数据操作语言),一句话概括:
对表里的数据记录做增、删、改。
注意它的对象是数据(行记录),不是表结构。建表、删表、改字段属于 DDL,别搞混。
DML 一共就三个动作,记住这张地图就够了:
| 动作 | 关键字 | 作用 | 类比 Excel |
|---|---|---|---|
| 增 | INSERT / REPLACE INTO |
往表里加一行数据 | 新增一行记录 |
| 改 | UPDATE |
修改已有数据的某些字段 | 改某个单元格 |
| 删 | DELETE / TRUNCATE |
删除整行记录 | 删除整行 |
二、INSERT:往表里加数据
1. 三种写法
sql
-- ① 全字段插入一条
INSERT [INTO] 表名 VALUES (值1, 值2, ..., 值n);
-- ② 指定字段插入一条(没写的字段用默认值或 NULL)
INSERT [INTO] 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);
-- ③ 批量插入多条(逗号隔开即可)
INSERT [INTO] 表名 VALUES (值1, 值2, ...), (值1, 值2, ...);
INSERT [INTO] 表名 (字段1, 字段2) VALUES (值1, 值2), (值1, 值2);
[INTO]里的方括号表示可写可不写,效果一样。
2. 三条铁律(最容易踩坑的地方)
-
字段顺序必须和值的顺序一一对应。 写
INSERT INTO 表 (id, name) VALUES (...),值就必须按 id、name 的顺序给。 -
字符串和日期型数据必须加引号 (单引号、双引号都行)。 数字可以不加,但
'2000-10-01'这种日期必须加,否则会被当成算式。 -
注意数据的合法范围,特殊字符要转义。
-
插入特殊字符时用
\做前缀转义; -
日期注意范围,比如
'1235-9-1'可能超出 DATE 有效范围,会报 warning; -
字段有长度/类型限制,超了会被截断或报错。
-
3. 实战演示
先建一张学生表:
sql
CREATE TABLE student2 (
id INT PRIMARY KEY,
name VARCHAR(30) NOT NULL,
sex CHAR(2) DEFAULT '女',
birthday DATE
);
全字段插入:
sql
INSERT INTO student2 VALUES (1001, '李成峰', '男', '2000-10-1');
指定字段插入 (只给 id 和 name,sex 自动填默认值 '女',birthday 为 NULL):
sql
INSERT INTO student2 (id, name) VALUES (1002, '颖');
-- 结果:1002 | 颖
佳颖 | 女 | NULL
批量插入 (日期还可以用函数 now() 取当前时间):
sql
INSERT INTO student2 VALUES
(1003, '孙德胜', '男', '1998-12-31'),
(1004, '凤飞飞', '女', '2009/3/15'),
(1005, '张无忌', '男', now());
小提示:MySQL 对日期格式比较宽容,
'2000-10-1'、'2009/3/15'都能被识别成标准日期。
三、REPLACE:插入遇到重复主键怎么办?
这是本节的一个重点对比。
| INSERT | REPLACE INTO | |
|---|---|---|
| 没有冲突 | 正常插入一行 | 正常插入一行(和 INSERT 一样) |
| 主键 / 唯一键冲突 | 直接报错,不插入(ERROR 1062) | 先删掉旧行,再插入新行 |
| 本质 | 纯新增 | DELETE + INSERT 二合一 |
示例:
sql
-- 1005 已存在,主键冲突 → 报错
INSERT INTO student2 VALUES (1005, '尹志平', '男', '1235-9-1');
-- ERROR 1062 (23000): Duplicate entry '1005' for key 'student2.PRIMARY'
-- 改用 replace:把原 1005 删掉,再插入新数据(返回 2 rows affected)
REPLACE INTO student2 VALUES (1005, '尹志平', '男', '1235-9-1');
REPLACE 的最大好处 :把「删除 + 插入」合二为一,在效果上相当于一次覆盖式更新。 注意它是真的"先删后插",所以没写到的字段会被重置为默认值,不会保留旧值。
四、UPDATE:修改已有数据
1. 语法
sql
UPDATE 表名 SET 字段1 = 值1, 字段2 = 值2, ... [WHERE 条件];
2. 示例
sql
UPDATE student2 SET birthday = '2012-12-12' WHERE id = 1002;
-- Rows matched: 1 Changed: 1
3. 两个必须记住的注意点
① WHERE 条件一般一定要写,否则是"悲伤的故事"。
sql
UPDATE student2 SET birthday = now(); -- 没有 WHERE!
-- 结果:表里 5 行全部被改成同一个日期
这个例子里 5 行数据全被改了,生产环境这么做基本等于事故。
② 生产环境的表通常有 update_time 字段,改数据时顺手把它更新成当前时间:
sql
UPDATE student2 SET name = '张三', update_time = now() WHERE id = 1001;
4. 补充:想"删掉"某个字段的值?
DELETE 只能删整行,不能删某个字段。想让某个字段变空,用 UPDATE 把它置为 NULL:
sql
UPDATE student2 SET birthday = NULL WHERE id = 1002;
五、DELETE 与 TRUNCATE:删除数据
1. 语法
sql
DELETE FROM 表名 [WHERE 条件]; -- 按条件删
TRUNCATE TABLE 表名; -- 清空整张表
2. 示例
sql
DELETE FROM student2 WHERE id = 1005; -- 只删 1005 这一行
DELETE FROM student2; -- 不加 WHERE → 清空整表所有记录
注意:不加
WHERE的DELETE会清掉全部数据,但表结构还在。
3. delete / truncate / drop 三者区别(高频考点)
| 对比项 | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| 删什么 | 表中的数据(可加条件删部分) | 表中的所有数据 | 数据 + 表结构,整张表消失 |
| 表结构 | 保留 | 保留 | 不保留 |
| 能否回滚 | 可以(事务内) | 不可以 | 不可以 |
| 速度 | 数据量大时很慢(逐行删) | 快(一次性清空) | 最快 |
怎么选:
-
只想删某几行 →
DELETE ... WHERE -
想清空整表、不要回滚、追求速度 →
TRUNCATE -
这张表彻底不想要了 →
DROP
六、一页速查表
sql
--
增
INSERT INTO 表 VALUES (...); -- 全字段
INSERT INTO 表 (字段1, 字段2) VALUES (...); -- 指定字段
INSERT INTO 表 VALUES (...), (...); -- 批量
REPLACE INTO 表 VALUES (...); -- 有冲突就覆盖(删+插)
-- 改
UPDATE 表 SET 字段 = 值 WHERE 条件; -- 千万别漏 WHERE
-- 删
DELETE FROM 表 WHERE 条件; -- 按条件删行
TRUNCATE TABLE 表; -- 清空表(不可回滚)
七、记忆口诀
增用 INSERT,覆盖用 REPLACE; 改用 UPDATE,WHERE 别忘记; 删行 DELETE,清表 TRUNCATE, 连表一起没,那就用 DROP喽。