INSERT、UPDATE、DELETE
增删改与 WHERE 安全写法。
INSERT、UPDATE、DELETE
这一课你将能做到
- 用 INSERT 完成单行、批量、
INSERT … SELECT三种写入,并理解自增主键的行为 - 安全地执行 UPDATE / DELETE:先 SELECT 验证、带 WHERE、必要时用事务兜底
- 说清 DELETE / TRUNCATE / DROP 的区别,以及生产环境为什么流行软删除
为什么要学
前 5 课全是只读,这一课开始动数据。后端的写接口——注册建用户、下单扣库存、删除草稿——最终都是一条 DML。DML 的特点是不可逆倾向:SELECT 写错大不了重查,UPDATE 少个 WHERE 就是全表事故。所以这一课一半在教语法,另一半在教「改数据的纪律」,这些纪律在面试和事故复盘里反复出现。
先建立图像
写操作的三种粒度:
INSERT:往表尾追加行 (行级,安全,自增 id 顺序分配)
UPDATE:原地修改匹配的行 (改多少行 = WHERE 匹配多少行,忘 WHERE = 全表)
DELETE:删除匹配的行 (同上,且可能沿外键 CASCADE 连锁删除)
TRUNCATE:整表清空 (表级,秒级,不可逐行回滚)
DROP:表都没了 (结构+数据全毁)
核心心智模型:UPDATE / DELETE 的影响范围 = WHERE 条件选中的行。写之前先用同一条 WHERE 跑 SELECT,看看会命中谁。
跟着做
本课会真正改动数据。玩坏了没关系:回第一课整段重跑建库脚本即可复原。以下语句在
sql_practice执行。
步骤 1:INSERT 指定列 + 批量
INSERT INTO student (name, email, city, vip, balance)
VALUES ('测试一号', 'test1@example.com', '深圳', 0, 0.00);
SELECT id, name, email FROM student WHERE email = 'test1@example.com';
-- id = 8:没写 id,自增主键自动分配
INSERT INTO student (name, email, city, vip, balance)
VALUES ('测试二号', 'test2@example.com', '杭州', 0, 10.00),
('测试三号', 'test3@example.com', '北京', 1, 66.00);
习惯从第一天养好:永远写列名清单,不依赖表的列顺序。表将来加列,这种 INSERT 一行不用改。
步骤 2:INSERT … SELECT 批量搬运
给小吴(id=7)生成「SQL 与关系型数据库」全部已发布课时的学习记录(尚未开始):
INSERT INTO study_record (student_id, lesson_id, completed)
SELECT 7, l.id, 0
FROM lesson l
WHERE l.course_id = 3
AND l.status = 'published'
AND NOT EXISTS (
SELECT 1 FROM study_record r
WHERE r.student_id = 7 AND r.lesson_id = l.id
);
-- 插入 3 行(course 3 的已发布课时 6、7、8)
NOT EXISTS 用来跳过已有记录——本表有唯一键 uk_student_lesson(student_id, lesson_id),重复插入会报 1062。批量初始化、老数据迁移,都是这个句式。
步骤 3:UPDATE 带 WHERE,先 SELECT 后 UPDATE
-- 第一步:用将要 UPDATE 的 WHERE 先查一遍,确认命中谁
SELECT id, name, balance FROM student WHERE id = 5; -- 小夏 88.00
-- 第二步:再改
UPDATE student SET balance = balance + 100 WHERE id = 5;
SELECT balance FROM student WHERE id = 5; -- 188.00