mysql如何搭建小型电商项目_mysql初级实战教程

来源:这里教程网 时间:2026-02-28 20:51:11 作者:

小型电商项目不需要一开始就上分布式或分库分表,MySQL 单实例 + 合理设计就能撑住日活几千的订单和商品查询。关键不是“怎么装 MySQL”,而是“怎么让表不拖垮查询、不锁死写入、不存错数据”。

商品和订单表必须加哪些索引

没索引的

orders
表查用户历史订单会全表扫描,10 万行就明显卡顿;
products
表没索引时按分类查商品,连后台管理都点不动。

orders
表至少要有:
user_id
(查某人全部订单)、
status
created_at
联合索引(查待发货/近 7 天订单)
products
表必须有:
category_id
(前台分类页)、
status
(只查上架中商品)、
id
主键之外,别忘了
sku
字段要加唯一索引——防止重复上架同一 SKU
避免在
WHERE
里对字段做函数操作,比如
WHERE DATE(created_at) = '2024-05-01'
会让索引失效,改用
WHERE created_at >= '2024-05-01' AND created_at 

库存扣减为什么不能只靠 UPDATE ... SET stock = stock - 1

并发下单时,两个请求同时读到 stock=5,各自减 1 写回 4,实际卖了两单却只扣了一次库存——超卖就发生了。

必须用原子操作:
UPDATE products SET stock = stock - 1 WHERE id = ? AND stock >= 1
,检查影响行数是否为 1
如果影响行为 0,说明库存不足或已被抢完,应用层要立刻返回“库存不足”,不能重试或忽略 别依赖事务隔离级别来防超卖(比如设成
REPEATABLE READ
),它解决不了这个场景;真正起作用的是 WHERE 条件里的
stock >= 1
这个约束

订单状态变更该用 ENUM 还是 tinyint

ENUM('pending', 'paid', 'shipped', 'completed', 'cancelled')
看着清晰,但上线后加个“refunding”状态就得 ALTER TABLE,锁表时间长,小项目也扛不住。

一律用
TINYINT UNSIGNED
,配合应用层定义常量,比如
1 → pending
2 → paid
状态流转逻辑必须收口在服务端代码里,数据库只做校验:比如不允许从
completed
直接跳回
paid
,就在 UPDATE 语句里写死允许的前驱状态:
WHERE status IN (1,2) AND id = ?
别把状态名硬编码在 SQL 里,更别用字符串匹配判断状态,
WHERE status = 'shipped'
WHERE status = 3
慢且不可靠

本地开发环境如何避免“上线就慢”

开发机跑得飞快,一上云服务器就慢半拍,大概率是配置没对齐,或者测试数据量级太假。

关掉
innodb_flush_log_at_trx_commit = 2
(开发可接受崩溃丢一秒日志),否则每条 INSERT 都刷盘,插入 1000 条订单要 10 秒+
导入测试数据别只插 10 条商品,至少 1 万行;用
INSERT INTO ... VALUES (),(),()...
批量插入,别循环单条
INSERT
执行慢查询前先
EXPLAIN
,重点关注
type
是否为
ALL
index
key
列是否用了预期索引,
rows
是否远超实际结果数

最容易被忽略的是字符集——所有表统一用

utf8mb4_unicode_ci
,别用
utf8
(它不支持 emoji),也别混用 collation,否则 JOIN 时隐式转换会悄悄干掉索引。

相关推荐