Administrator
Administrator
发布于 2026-10-27 / 0 阅读
0
0

数据库入门到初级(06):增删改入门:把数据真正用起来

数据库入门到初级 · 第 06/22 篇。实验口径:MySQL 8.4、InnoDB、utf8mb4。案例:小型商城。

上一篇建好了表,这一篇把商品和订单放进去。增删改看起来只有三种命令,但真正需要养成的是一个操作习惯:知道自己正在改哪条数据,并检查实际结果。

1. 先装入整个系列的数据

前提:已按第 5 篇创建四张空表。如果第 3 篇已导入完整 SQL,请跳过本节。以下数据只插入一次。

INSERT INTO users (id,name,email,phone,created_at) VALUES
(1,'小林','lin@example.test','13900000001','2026-01-01 09:00:00'),
(2,'小周','zhou@example.test',NULL,'2026-01-02 09:00:00'),
(3,'小陈','chen@example.test','','2026-01-03 09:00:00');

INSERT INTO products (id,name,price,stock,is_on_sale,created_at) VALUES
(1,'机械键盘',199.00,20,1,'2026-01-01 10:00:00'),
(2,'无线鼠标',89.00,30,1,'2026-01-01 10:00:00'),
(3,'笔记本支架',129.00,10,1,'2026-01-02 10:00:00'),
(4,'数据线',29.00,0,1,'2026-01-03 10:00:00'),
(5,'旧款耳机',299.00,5,0,'2026-01-04 10:00:00');

INSERT INTO orders (id,user_id,status,total_amount,created_at) VALUES
(1001,1,'paid',288.00,'2026-01-10 10:00:00'),
(1002,1,'paid',129.00,'2026-01-11 11:00:00'),
(1003,2,'pending',178.00,'2026-01-12 12:00:00'),
(1004,2,'cancelled',29.00,'2026-01-13 13:00:00');

INSERT INTO order_items (id,order_id,product_id,product_name,unit_price,quantity) VALUES
(1,1001,1,'机械键盘',199.00,1),
(2,1001,2,'无线鼠标',89.00,1),
(3,1002,3,'笔记本支架',129.00,1),
(4,1003,2,'无线鼠标',89.00,2),
(5,1004,4,'数据线',29.00,1);

现在有 3 名用户、5 件商品、4 张订单和 5 条明细。小林有两张已支付订单,小周有一张待支付和一张已取消订单,小陈没有订单。我们故意保留这些差异,方便后面解释连接、分组和空值。

2. INSERT:明确告诉数据库每个值属于哪一列

START TRANSACTION;
INSERT INTO products (name, price, stock, is_on_sale)
VALUES ('练习笔记本', 19.90, 50, 1);
SELECT LAST_INSERT_ID() AS new_product_id;
ROLLBACK;

这里没有写 id,由自增机制分配;创建时间使用默认值。LAST_INSERT_ID() 在当前连接获取刚才生成的自增编号,不能换到另一条连接查询。练习最后回滚,所以不会把新商品留在样例中,但自增编号可能留下空缺。

尽量显式写列名。INSERT INTO products VALUES (...) 把值的位置与表结构绑定得很紧,后面加列或调整结构时更容易出错。

3. UPDATE:先选中,再修改

增删改前后的检查流程

START TRANSACTION;
SELECT id, name, price FROM products WHERE id = 1;
UPDATE products SET price = 189.00 WHERE id = 1;
SELECT ROW_COUNT() AS affected_rows;
SELECT id, name, price FROM products WHERE id = 1;
ROLLBACK;

先确认 1 号确实是机械键盘,再修改,最后验证。ROW_COUNT() 紧接修改语句使用;是否把“匹配但值未改变”的记录算入影响行数,还会受到客户端连接选项影响,不能仅凭界面数字推断全部业务含义。

库存增加时可以写 SET stock = stock + 5。它让数据库直接在当前值上做运算,比应用先查出 20、算成 25、再覆盖回去更适合并发场景。扣减库存还需要增加库存充足条件,第 18 篇会说明。

4. DELETE:删的是记录,不是表结构

START TRANSACTION;
INSERT INTO products (id, name, price, stock, is_on_sale)
VALUES (90001, '待删除练习商品', 1.00, 0, 0);
SELECT * FROM products WHERE id = 90001;
DELETE FROM products WHERE id = 90001;
SELECT COUNT(*) AS remaining FROM products WHERE id = 90001;
ROLLBACK;

练习编号 90001 只用于新建样例库,若你已有相同编号,换一个未使用的编号。删除后 remaining 为 0。这个商品没有订单引用,因此可以删除。

如果直接删除样例中的机械键盘,可能被订单明细外键阻止。不要为了让删除成功而随手关闭外键检查,先确认业务到底需要删除商品,还是把 is_on_sale 改为 0 来下架。

DELETE FROM products; 没有 WHERE,会尝试删除全表记录。DROP TABLE 删除表结构,TRUNCATE TABLE 清空表且属于 DDL;它们不适合拿来代替本篇可回滚的练习。

5. 什么时候提交,什么时候回滚

COMMIT 保存当前事务修改,ROLLBACK 撤销尚未提交的事务修改。本篇用 InnoDB 表,并且只在事务中演示 DML。连接可能默认自动提交,因此要先显式开始事务;已经提交的修改不能靠之后再写 ROLLBACK 找回来。

练习与答案

练习:把鼠标库存临时增加 5,再撤销。

START TRANSACTION;
UPDATE products SET stock = stock + 5 WHERE id = 2;
SELECT stock FROM products WHERE id = 2;
ROLLBACK;
SELECT stock FROM products WHERE id = 2;

两次查询应分别看到 35 和 30。若结果不同,先检查是否使用原始数据、是否在同一连接执行,以及中间是否已经提交。


上一篇:第 05 篇 · 系列目录 · 下一篇:第 07 篇


评论