订单快照设计:一个字段救了未来的自己
问题起源
用户下单时价格是 99 元,一周后商品涨价到 129 元。此时用户打开订单详情,应该看到哪个价格?
如果订单表只存 sku_id,那么每次查订单都要去商品表取最新价格——结果就是历史订单的价格会随商品涨价而变化。这在财务上完全不可接受。
解决方案
在 order_item 表里冗余三个字段:
| 字段 | 说明 |
|---|---|
sku_name | 下单瞬间的商品名 |
sku_pic | 下单瞬间的商品图 |
price | 下单瞬间的单价 |
CREATE TABLE order_item (
id BIGINT PRIMARY KEY,
order_id BIGINT NOT NULL,
sku_id BIGINT NOT NULL,
sku_name VARCHAR(200) NOT NULL COMMENT 下单时的商品名(快照),
sku_pic VARCHAR(500) COMMENT 下单时的商品图(快照),
price INT NOT NULL COMMENT 下单时的单价(快照),
quantity INT NOT NULL
);
为什么这是对的
数据冗余在这里不是缺点,而是正确设计。
商品名称改了,历史订单不应该跟着改——因为用户当时买的确实是那个名字。同理,价格、图片也一样。
延伸思考
这个思路可以推广到所有「状态会随时间变化,但历史记录必须冻结」的场景:
- 收货地址:订单要存地址快照,用户改了地址不影响历史订单
- 优惠券信息:存下单时的券面额
- 商品规格:存下单时选的规格描述
核心原则:订单是一个契约,契约签订时的条款不能被单方面修改。
评论
2加载中…