
一、电商系统有哪些核心业务一个最基本的电商系统包含用户注册 │ 浏览商品 │ 加入购物车 │ 提交订单 │ 支付 │ 发货 │ 收货 │ 完成订单根据业务我们先抽取实体。二、需求分析抽取业务实体数据库设计第一步不是建表而是找出业务中的名词。例如用户购买商品可以抽取用户User商品Product购物车Cart订单Order订单商品OrderItem支付Payment收货地址Address因此数据库至少需要User Product Cart Order Order_Item Payment Address三、实体之间的关系关系如下User │ ├──────────────┐ │ │ │ │ ▼ ▼ Cart Order │ │ │ │ ▼ ▼ Product Order_Item │ ▼ Product Order │ ▼ Payment User │ ▼ Address可以看到一个用户有多个订单一对多一个订单包含多个商品一对多一个商品可以出现在多个订单中多对多通过 Order_Item 实现一个用户可以有多个收货地址一对多四、用户表userCREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), password VARCHAR(255), phone VARCHAR(20), status TINYINT, create_time DATETIME );保存登录信息手机号用户状态不保存订单地址商品因为这些属于其他实体。五、商品表productCREATE TABLE product ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100), price DECIMAL(10,2), stock INT, status TINYINT, create_time DATETIME );字段说明字段作用name商品名称price当前售价stock库存status上架/下架create_time创建时间六、购物车表cart很多初学者认为订单就是购物车。其实不是。购物车只是临时保存。订单已经成交。购物车CREATE TABLE cart( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, product_id BIGINT, count INT );表示Tom ↓ 商品A 2件七、订单表orders很多新人喜欢这样设计order id user_id product_id count这是错误设计。为什么因为一个订单可以买手机 耳机 充电器不是一个商品。正确订单只保存订单信息。例如CREATE TABLE orders( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, total_amount DECIMAL(10,2), status TINYINT, create_time DATETIME );保存谁下单总金额状态时间不保存商品。八、订单详情表order_item⭐⭐⭐⭐⭐真正保存订单里面有哪些商品。CREATE TABLE order_item( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, product_id BIGINT, price DECIMAL(10,2), count INT );例如订单1001里面order_idproductcount1001手机11001耳机21001充电器1这就是订单详情。九、为什么订单要拆成两张表⭐⭐⭐⭐⭐这是面试高频问题。例如错误设计orders id user_id product_id count一个订单三个商品怎么办只能订单1001 手机 订单1001 耳机 订单1001 充电器订单信息重复三次。违反数据库规范。正确Order ↓ Order_ItemOrder保存订单信息。OrderItem保存商品信息。这样订单只保存一次。十、为什么订单金额不能实时计算⭐⭐⭐⭐⭐很多新人喜欢查询商品价格 × 数量计算订单金额。问题商品后来涨价。例如今天手机 5000下单。明天手机 6000如果实时计算历史订单全部变6000。错误。所以订单必须保存成交价即order_item.price。而不是每次查product.price。十一、库存为什么放在 Product因为库存属于商品当前状态。例如商品A 库存 100下单库存99。如果库存放订单。无法知道当前库存。十二、订单状态设计不要多个is_pay is_send is_finish推荐status例如status说明0待支付1已支付2已发货3已完成4已取消以后新增退款直接增加状态。十三、支付表payment为什么支付单独一张表因为订单可能多次支付。例如第一次失败。第二次成功。支付记录应该保留。CREATE TABLE payment( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, amount DECIMAL(10,2), pay_type VARCHAR(20), pay_time DATETIME, status TINYINT );十四、最终数据库结构User │ ┌──────────┴──────────┐ │ │ ▼ ▼ Address Orders │ ▼ Order_Item │ ▼ Product ▲ │ Cart Orders │ ▼ Payment十五、本章总结表作用user用户product商品cart购物车orders订单order_item订单商品payment支付记录address收货地址企业设计最重要的三个思想 ⭐⭐⭐⭐⭐① 一个订单对应多个商品所以必须Order ↓ OrderItem拆表。② 成交价格必须保存不要查询product.price实时计算。③ 支付记录独立方便退款。支付失败。支付历史。 本章核心一句话订单表记录一次交易订单详情表记录交易中的商品商品价格和支付信息都要在交易发生时固化保存不能依赖后续实时计算。本章思考题为什么orders和order_item必须拆成两张表而不能合成一张一个订单包含多个商品拆表可以减少数据冗余符合数据库规范。为什么order_item要保存商品成交价price而不能每次查询product.price保存交易快照避免商品价格变化影响历史订单。为什么购物车cart和订单orders不能设计成同一张表购物车是临时数据订单是正式业务数据生命周期不同。为什么支付记录payment通常独立成一张表而不是直接放在订单表中一个订单可能有多次支付行为需要完整保存支付历史。如果一个订单购买了 5 种商品在数据库中应该存储几条orders记录几条order_item记录为什么1 条 orders 记录 5 条 order_item 记录每种商品对应一条详情。