商品数据怎么建模:SPU、SKU 与规格的关系
商品模型定错了,后面所有功能都别扭。本文说明 SPU 与 SKU 的分工、规格组合怎么生成、以及价格和库存挂在哪一层。
- SPU 承载选择前固定的描述,SKU 是规格确定后的最小可售单位。
- 价格与库存必须挂在 SKU 层,SPU 上的价格区间应由 SKU 算出而非单独维护。
- 不要全量生成规格组合,只创建实际在售的,否则库存表迅速膨胀。
- 前端要能把不可选的规格组合置灰,这依赖接口返回可售组合信息。
- 订单必须保存商品名称、规格与价格的下单时快照,否则改价后历史订单说不清。
商品模型是电商系统的地基。它定错了,表现不是某个功能做不出来,而是每个功能都要绕一下 —— 搜索别扭、库存别扭、订单别扭、报表别扭。而改模型的代价随着数据量增长迅速上升。
两层的分工
SPU 是「一款商品」,承载面向用户的描述:名称、详情、图片、品类、品牌。SKU 是「一个可售卖的具体项」,是规格组合确定之后的最小单位:红色 XL 码这一件。
分工的判断标准很简单:用户在商品页上选择之后才确定的东西,属于 SKU 层;选择之前就固定的,属于 SPU 层。按这条划,多数字段的归属都不难决定。
价格和库存挂在 SKU
- 不同规格通常价格不同,库存一定不同,所以这两项必须在 SKU 层;
- SPU 上可以有一个展示用的价格区间,但它是从 SKU 算出来的,不应单独维护;
- 重量、体积这类影响运费的属性也在 SKU 层,因为不同规格的包装可能不同;
- 详情、图片在 SPU 层,但允许 SKU 覆盖部分图片 —— 用户切换颜色时主图应当跟着变。
规格组合不要全量生成
三个规格维度各五个选项,全量组合是一百二十五个 SKU,而实际在售的可能只有二十个。系统应当允许只创建实际存在的组合,而不是强制生成全部再逐个禁用 —— 后者会让库存表迅速膨胀,也让后台难以浏览。
前端展示时要处理不可选组合:用户选了红色之后,没有红色的尺码应当置灰而不是允许选中再报错。这需要接口返回可售组合的信息,是商品详情页接口设计里容易漏掉的一项。
订单必须保存快照
订单里不能只存商品 ID。商品名称、规格、价格在下单那一刻的值必须一并存进订单 —— 否则商品改名或调价之后,历史订单显示的就是新信息,对账和客诉都说不清。
这是商品建模里最常被忽略、代价也最大的一条。补救很困难,因为历史数据已经丢了当时的值。
给扩展留位置
不同品类需要的属性差别很大,服装要尺码材质,电器要功率型号。把所有属性都做成固定字段会让表结构臃肿,可行的做法是核心字段固定、品类特有属性用可扩展的结构存放,并在前端按品类模板渲染。相关实现见电商网站 / 商城定制与平台与系统开发。
常见问题
SPU 和 SKU 怎么区分?
判断标准是用户在商品页上选择之后才确定的属于 SKU,选择之前就固定的属于 SPU。名称、详情、图片、品类在 SPU 层;具体规格组合、价格、库存、重量在 SKU 层。按这条划分,多数字段的归属都不难决定。
规格组合要全部创建出来吗?
不要。三个维度各五个选项全量组合是一百二十五个,实际在售可能只有二十个。系统应允许只创建真实存在的组合,全量生成再逐个禁用会让库存表膨胀且后台难以浏览。
商品改价后历史订单会变吗?
如果订单只存了商品 ID 就会变,这是常见且代价很大的建模错误。订单必须保存下单时刻的商品名称、规格和价格快照,否则改名或调价后历史订单显示的是新信息,对账与客诉都无法说清,而且事后无法补救。
参考资料
- Shopify Themes Documentation · Shopify
- WooCommerce Documentation · WooCommerce