好的,用户问的是产品SKU数据库设计,首先得确定他们的使用场景。可能是在开发电商平台或者库存管理系统,需要处理商品的多属性问题。
用户身份可能是产品经理、开发者或者初创公司的技术负责人,可能对数据库有一定了解但需要最佳实践。深层需求可能是确保系统能灵活处理不同商品类型,避免后期扩展困难。
得考虑常见问题,比如属性冗余、查询效率低。需要强调范式化和反范式化的平衡,还有EAV模型的利弊。可能用户没明说但需要高性能和易维护的方案。
还要举例说明,让设计更具体,比如用手机的例子来展示多属性怎么存储。得提醒他们注意索引和缓存,毕竟电商场景下查询压力大。
好的,产品SKU的数据库设计是电商系统中最核心、最复杂的设计之一。一个好的设计能够灵活支持商品的多属性(如颜色、尺寸、版本等),并且保证库存管理的准确性和高性能。
下面我将为您提供一个经典、灵活且高效的数据库设计方案,并解释每个表的作用和关联关系。
核心设计理念
采用“SPU + SKU”的模型,并将属性与商品解耦,通过关联表来管理,以实现最大的灵活性。
SPU (Standard Product Unit):标准化产品单元。定义一组商品的共享属性(如名称、描述、品牌、分类等)。例如:
iPhone 15就是一个SPU。SKU (Stock Keeping Unit):库存保有单位。基于SPU,通过特定的属性(如“红色”、“128GB”)定义到具体的商品型号。库存管理和下单的最小单位。例如:
iPhone 15 红色 128GB就是一个SKU。
推荐数据库表结构
以下是核心的6张表:
1. 商品SPU表 (spu_table)
存储所有商品的公共信息。
sql
CREATE TABLE `spu` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'SPU ID',
`spu_code` varchar(64) NOT NULL COMMENT 'SPU编码,唯一',
`name` varchar(128) NOT NULL COMMENT '商品名称(标题)',
`description` text COMMENT '商品详细描述',
`category_id` bigint(20) NOT NULL COMMENT '所属分类ID',
`brand_id` bigint(20) DEFAULT NULL COMMENT '品牌ID',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态:1-上架 0-下架 -1-删除',
`creator` varchar(64) DEFAULT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updater` varchar(64) DEFAULT NULL,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_spu_code` (`spu_code`),
KEY `idx_category_brand` (`category_id`,`brand_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品SPU表';2. 商品SKU表 (sku_table)
存储每个具体型号的库存、价格等信息。一个SPU对应多个SKU。
sql
CREATE TABLE `sku` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'SKU ID',
`sku_code` varchar(64) NOT NULL COMMENT 'SKU编码,唯一',
`spu_id` bigint(20) NOT NULL COMMENT '所属SPU ID',
`name` varchar(255) NOT NULL COMMENT 'SKU名称(通常由SPU名+规格值组成,如:iPhone 15 红色 128GB)',
`price` decimal(10,2) NOT NULL COMMENT '销售价格',
`cost_price` decimal(10,2) DEFAULT NULL COMMENT '成本价',
`stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存数量',
`warning_stock` int(11) DEFAULT '0' COMMENT '库存预警值',
`image_url` varchar(255) DEFAULT NULL COMMENT '主图(SKU级别的主图,如红色手机图片)',
`status` tinyint(4) DEFAULT '1' COMMENT '状态',
`creator` varchar(64) DEFAULT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updater` varchar(64) DEFAULT NULL,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_sku_code` (`sku_code`),
KEY `idx_spu_id` (`spu_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品SKU表';3. 商品属性键表 (attr_key)
定义所有可能的属性名(键),这些属性可以被不同分类的商品复用。
sql
CREATE TABLE `attr_key` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '属性键ID',
`name` varchar(64) NOT NULL COMMENT '属性名称(如:颜色、尺寸、版本)',
`category_id` bigint(20) NOT NULL COMMENT '所属分类ID(属性可以按分类管理)',
`is_sale` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否是销售属性(1-是,0-否。销售属性才能生成SKU,如颜色;非销售属性是商品描述,如操作系统)',
`sort` int(11) DEFAULT '0' COMMENT '排序',
`creator` varchar(64) DEFAULT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品属性键表';4. 商品属性值表 (attr_value)
存储属性键对应的所有可能的值。
sql
CREATE TABLE `attr_value` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '属性值ID',
`attr_key_id` bigint(20) NOT NULL COMMENT '对应的属性键ID',
`value` varchar(64) NOT NULL COMMENT '属性值(如:红色、128GB、XXL)',
`sort` int(11) DEFAULT '0' COMMENT '排序',
`creator` varchar(64) DEFAULT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_attr_key_id` (`attr_key_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品属性值表';5. SKU销售属性关联表 (sku_sale_attr_value)
这是整个设计的精髓。它记录了每个SKU是由哪些具体的销售属性值组合而成的。
sql
CREATE TABLE `sku_sale_attr_value` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`sku_id` bigint(20) NOT NULL COMMENT 'SKU ID',
`spu_id` bigint(20) NOT NULL COMMENT 'SPU ID(冗余字段,便于查询)',
`attr_key_id` bigint(20) NOT NULL COMMENT '销售属性键ID',
`attr_value_id` bigint(20) NOT NULL COMMENT '销售属性值ID',
`attr_value` varchar(64) NOT NULL COMMENT '属性值(冗余存储,避免连表查询)',
`creator` varchar(64) DEFAULT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_sku_attr` (`sku_id`,`attr_key_id`), -- 一个SKU的同一个属性只能有一个值
KEY `idx_spu_id` (`spu_id`) -- 便于根据SPU查询所有SKU的属性
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='SKU销售属性值表';注意:这里的 attr_value 字段是冗余存储,用空间换时间,避免前端展示SKU详情时频繁地联表查询attr_value表。
6. SPU属性关联表 (spu_attr_value)
记录SPU与非销售属性的关系(商品描述性信息)。
sql
CREATE TABLE `spu_attr_value` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`spu_id` bigint(20) NOT NULL COMMENT 'SPU ID',
`attr_key_id` bigint(20) NOT NULL COMMENT '属性键ID',
`attr_value_id` bigint(20) NOT NULL COMMENT '属性值ID',
`attr_value` varchar(255) NOT NULL COMMENT '属性值(同样可以冗余)',
`creator` varchar(64) DEFAULT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_spu_id` (`spu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='SPU属性值表(非销售属性)';关系图与查询示例
ER关系简图
text
+-------------+ +-------------+ +-----------------------+
| spu |1 n| sku |1 n| sku_sale_attr_value |
| |------| |------| |
+-------------+ +-------------+ +-----------------------+
| |
| 1 | n
| n | 1
+-----------------+ +-------------+
| spu_attr_value | | attr_key |
+-----------------+ +-------------+
| | 1
| n | n
+-------------+ +-------------+
| attr_value | | category |
+-------------+ +-------------+查询示例:获取某个SPU(如ID=123)下的所有SKU及其对应的销售属性
sql
SELECT
s.id AS sku_id,
s.sku_code,
s.name AS sku_name,
s.price,
s.stock,
GROUP_CONCAT(
CONCAT(sav.attr_key_id, ':', sav.attr_value_id, ':', sav.attr_value)
SEPARATOR '; '
) AS sale_attributes -- 将销售属性拼接成一个字段
FROM
sku s
LEFT JOIN
sku_sale_attr_value sav ON s.id = sav.sku_id
WHERE
s.spu_id = 123
GROUP BY
s.id;前端或服务层再解析 sale_attributes 字段,即可生成SKU选择器。
设计要点与考虑
灵活性:属性可以动态增删,并能被不同分类的商品复用。
性能:
冗余字段:在
sku_sale_attr_value和spu_attr_value中冗余存储了attr_value和spu_id,极大地提高了查询速度,是常见的空间换时间的优化策略。索引:在所有常用的查询字段(如
spu_id,sku_code,category_id)上建立索引。
库存管理:库存数量(
stock)保存在sku表,是原子操作的最小单位。所有库存操作(扣减、增加)都必须基于SKU ID进行。SKU编码:
sku_code需要保证全局唯一,通常有固定的生成规则(如:SPU编码 + 属性值编码的某种组合)。扩展考虑:
价格体系:如果价格策略复杂(如会员价、活动价),需要单独设计
价格表。图片 gallery:如果需要多个SKU图片,可以设计
sku_image表。条形码:可以在
sku表中增加barcode字段。
这个设计经过了大量电商项目的验证,在灵活性和性能之间取得了很好的平衡,可以作为您系统设计的坚实基础。
开启新对话
内容