电商 SPU 与 SKU 详解
一、概念定义
1. SPU(Standard Product Unit,标准产品单位)
SPU 是商品的"属性集合",代表"是什么商品",是商品的最小聚合单位。
它是一组可复用、易检索的标准化信息的集合,描述的是商品的核心属性(如品牌、型号、名称、类目),但不包含具体的销售规格。
通俗理解:SPU = "同一款商品",不管它有多少个颜色、多少种容量,只要核心属性相同,就属于同一个 SPU。
- 例:iPhone 15 Pro Max 就是一个 SPU
- 例:农夫山泉 550ml 就是一个 SPU
2. SKU(Stock Keeping Unit,库存量单位)
SKU 是库存控制的最小可用单位,代表"具体怎么卖",是可以被采购、存储、售卖、统计的具体商品实例。
通俗理解:SKU = "某个具体规格的商品",一个 SPU 下可以有多个 SKU,每个 SKU 对应一个库存量、一个价格、一个可售卖的条形码。
- 例:iPhone 15 Pro Max「原色 / 256G」是一个 SKU
- 例:iPhone 15 Pro Max「黑色 / 512G」是另一个 SKU
二、SPU 与 SKU 的关系
graph TD
subgraph SPU["SPU(标准产品单位)"]
A["iPhone 15 Pro Max"]
end
subgraph SKU1["SKU-1"]
A1["颜色:原色 / 内存:256G"]
A1 --> P1["价格:¥9999<br/>库存:100"]
end
subgraph SKU2["SKU-2"]
A2["颜色:原色 / 内存:512G"]
A2 --> P2["价格:¥11999<br/>库存:50"]
end
subgraph SKU3["SKU-3"]
A3["颜色:黑色 / 内存:256G"]
A3 --> P3["价格:¥9999<br/>库存:80"]
end
A --> SKU1
A --> SKU2
A --> SKU3
一句话总结:
SPU = 商品的"身份证"(核心属性,不涉及具体规格)
SKU = 商品的"库存条码"(每个具体规格的售卖单元)
1 个 SPU ──► 多个 SKU(通过"销售属性"组合生成)
| 对比维度 | SPU | SKU |
|---|---|---|
| 全称 | Standard Product Unit | Stock Keeping Unit |
| 含义 | 标准产品单位 | 库存量单位 |
| 回答的问题 | 这是什么商品? | 怎么卖?什么规格? |
| 是否含规格 | ❌ 不含销售规格 | ✅ 包含全部销售规格 |
| 是否管库存 | ❌ 不管 | ✅ 每个 SKU 独立管库存 |
| 是否定价格 | ❌ 通常不定 | ✅ 每个 SKU 独立定价 |
| 有无独立条形码 | ❌ 无 | ✅ 有(EAN/UPC 等) |
| 数量级 | 少(商品数) | 多(规格组合数) |
| 举例 | iPhone 15 Pro Max | iPhone 15 Pro Max 原色 256G |
三、关键概念:销售属性(决定 SKU 的维度)
SKU 是由销售属性组合决定的。销售属性是指"顾客下单时必须选择、且影响价格/库存"的规格。
常见销售属性:
- 手机:颜色、内存容量、版本(国行/港版)
- 服装:颜色、尺码
- 饮料:口味、容量
- 电脑:CPU、内存、硬盘、显卡
用数学理解:SKU 数量 = 各销售属性可选值的笛卡尔积(但实际只保留有货的组合)。
graph LR
subgraph 属性维度
C["颜色<br/>原色 / 黑色 / 白色"]
M["内存<br/>256G / 512G"]
end
C --> S1["SKU: 原色-256G"]
C --> S2["SKU: 原色-512G"]
M --> S1
M --> S2
四、数据模型设计(数据库表结构)
电商商品系统中,通常用 4 张核心表管理 SPU / SKU:
erDiagram
SPU ||--o{ SKU : "包含"
SPU ||--o{ SPU_ATTR : "拥有"
CATEGORY ||--o{ SPU : "分类下"
SKU ||--o{ SKU_ATTR : "拥有"
CATEGORY {
bigint category_id PK "类目ID"
varchar name "类目名"
}
SPU {
bigint spu_id PK
bigint category_id FK "所属类目"
varchar spu_name "商品名称"
varchar brand "品牌"
varchar main_image "主图"
varchar description "详情描述"
}
SPU_ATTR {
bigint attr_id PK
bigint spu_id FK
varchar attr_name "属性名"
varchar attr_value "属性值"
tinyint is_sale "是否销售属性"
}
SKU {
bigint sku_id PK
bigint spu_id FK "所属SPU"
varchar sku_no "SKU编码/条码"
decimal price "售价"
int stock "库存"
varchar image "规格图片"
}
SKU_ATTR {
bigint id PK
bigint sku_id FK
varchar attr_name "销售属性名"
varchar attr_value "销售属性值"
}
建表 SQL 示例
-- 类目表
CREATE TABLE `category` (
`category_id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(64) NOT NULL COMMENT '类目名称',
`parent_id` BIGINT DEFAULT 0 COMMENT '父类目ID,0为顶级'
) COMMENT '商品类目表';
-- SPU 表:标准产品单位
CREATE TABLE `spu` (
`spu_id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`category_id` BIGINT NOT NULL COMMENT '所属类目',
`spu_name` VARCHAR(255) NOT NULL COMMENT '商品名称',
`brand` VARCHAR(64) COMMENT '品牌',
`main_image` VARCHAR(255) COMMENT '商品主图',
`description` TEXT COMMENT '商品详情描述',
`status` TINYINT DEFAULT 1 COMMENT '状态:1上架 0下架'
) COMMENT 'SPU表';
-- SPU 属性表:商品的核心属性
CREATE TABLE `spu_attr` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`spu_id` BIGINT NOT NULL COMMENT 'SPU ID',
`attr_name` VARCHAR(64) NOT NULL COMMENT '属性名,如"屏幕尺寸"',
`attr_value` VARCHAR(255) NOT NULL COMMENT '属性值,如"6.7英寸"',
`is_sale` TINYINT DEFAULT 0 COMMENT '是否销售属性:1是 0否'
) COMMENT 'SPU属性表';
-- SKU 表:库存量单位
CREATE TABLE `sku` (
`sku_id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`spu_id` BIGINT NOT NULL COMMENT '所属SPU',
`sku_no` VARCHAR(64) NOT NULL COMMENT 'SKU编码/条形码',
`price` DECIMAL(10,2) NOT NULL COMMENT '售价',
`stock` INT DEFAULT 0 COMMENT '库存量',
`image` VARCHAR(255) COMMENT '规格图片'
) COMMENT 'SKU表';
-- SKU 属性表:决定 SKU 的销售属性组合
CREATE TABLE `sku_attr` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`sku_id` BIGINT NOT NULL COMMENT 'SKU ID',
`attr_name` VARCHAR(64) NOT NULL COMMENT '销售属性名,如"颜色"',
`attr_value` VARCHAR(64) NOT NULL COMMENT '销售属性值,如"原色"'
) COMMENT 'SKU销售属性表';
五、电商系统中 SPU / SKU 的应用
1. 商品管理流程
flowchart TD
A["商家创建商品"] --> B["新建 SPU<br/>填写核心属性+类目"]
B --> C["选择销售属性维度<br/>(如颜色、内存)"]
C --> D["为每个规格组合创建 SKU<br/>设置价格+库存+条码"]
D --> E["上架商品"]
E --> F["用户下单购买具体 SKU"]
F --> G["扣减对应 SKU 库存"]
2. 各业务环节关注点
| 业务环节 | 使用 SPU | 使用 SKU |
|---|---|---|
| 商品搜索/展示 | 用 SPU 去重,展示商品主信息 | 详情页切换规格时展示 |
| 商品详情页 | 展示核心属性、详情图 | 展示价格区间、规格选择器 |
| 购物车/下单 | — | 锁定具体 SKU |
| 库存管理 | — | 按 SKU 独立扣减库存 |
| 价格管理 | 展示价格区间(min~max) | 每个 SKU 独立定价 |
| 订单/售后 | — | 记录具体 SKU,发货/退款按 SKU 处理 |
| 报表统计 | 按 SPU 汇总商品维度 | 按 SKU 汇总销量/库存维度 |
3. 一个完整的例子:电商服装店
SPU: 夏季纯棉T恤(品牌:ABC,面料:纯棉,版型:宽松)
├── SKU-1001: 颜色=白色, 尺码=M, 价格=¥59, 库存=200
├── SKU-1002: 颜色=白色, 尺码=L, 价格=¥59, 库存=150
├── SKU-1003: 颜色=黑色, 尺码=M, 价格=¥59, 库存=180
├── SKU-1004: 颜色=黑色, 尺码=L, 价格=¥59, 库存=120
└── SKU-1005: 颜色=蓝色, 尺码=XL, 价格=¥69, 库存=50(大码加价)
该 SPU 共有 3 种颜色 × 2~3 种尺码,实际生成 5 个有货 SKU。
六、常见问题与设计要点
1. SKU 数量爆炸问题
- 销售属性过多 → SKU 数量 = 笛卡尔积,管理成本剧增。
- 对策:属性分级,仅有影响价格/库存的属性设为销售属性;无关属性放入 SPU 的普通属性。
2. 规格组合不可用问题
- 某些组合可能没有货(如"白色-XL"停产)。
- 对策:前端根据库存动态禁用无货 SKU,后台可配置禁用组合。
3. 价格与库存的粒度
- 价格、库存、条形码、图片都必须挂在 SKU 层,不能挂在 SPU 层。
- SPU 展示"价格区间"(如 ¥59 ~ ¥69)由 SKU 价格聚合得出。
4. 数据库主键策略
- 高并发下单时 SKU 扣库存是热点,建议 SKU 主键用
BIGINT(雪花算法等),配合乐观锁/行锁扣减库存。
5. 与规格属性(specs)的关系
- 规格属性(如屏幕尺寸、电池容量)= 决定 SPU 归属的非销售属性,通常放 SPU 层。
- 销售属性(如颜色、内存)= 决定 SKU 划分的属性,放 SKU 层。
- 一个属性是否"销售属性"取决于它是否参与用户购买选择并影响价格/库存。
七、总结
┌─────────────────────────────┐
│ SPU 标准产品单位 │
│ iPhone 15 Pro Max │
│ (品牌/型号/核心属性,无规格) │
└──────────────┬──────────────┘
│ 1
│ 拥有
│ n
┌──────────────────────────┼──────────────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ SKU-1 │ │ SKU-2 │ │ SKU-3 │
│ 原色 256G │ │ 原色 512G │ │ 黑色 256G │
│ ¥9999 / 100 │ │ ¥11999 / 50 │ │ ¥9999 / 80 │
│ 库存量单位 │ │ 库存量单位 │ │ 库存量单位 │
└──────────────┘ └──────────────┘ └──────────────┘
SPU 管"商品"(描述),SKU 管"售卖"(价格 + 库存 + 条码)
- SPU:管"这是什么商品",负责搜索、详情、类目聚合。
- SKU:管"具体怎么卖",负责价格、库存、下单、发货、统计。
类比理解:
- SPU ≈ 车型(如"特斯拉 Model 3")——一个型号
- SKU ≈ 具体配置(如"Model 3 后驱 / 白 / 标准续航")——能下单的那一个
评论