Administrator
发布于 2025-08-23 / 46 阅读
0
0

商品型号、属性数据库关系设计SKU数据库设计及关系


好的,用户问的是产品SKU数据库设计,首先得确定他们的使用场景。可能是在开发电商平台或者库存管理系统,需要处理商品的多属性问题。

用户身份可能是产品经理、开发者或者初创公司的技术负责人,可能对数据库有一定了解但需要最佳实践。深层需求可能是确保系统能灵活处理不同商品类型,避免后期扩展困难。

得考虑常见问题,比如属性冗余、查询效率低。需要强调范式化和反范式化的平衡,还有EAV模型的利弊。可能用户没明说但需要高性能和易维护的方案。

还要举例说明,让设计更具体,比如用手机的例子来展示多属性怎么存储。得提醒他们注意索引和缓存,毕竟电商场景下查询压力大。

好的,产品SKU的数据库设计是电商系统中最核心、最复杂的设计之一。一个好的设计能够灵活支持商品的多属性(如颜色、尺寸、版本等),并且保证库存管理的准确性和高性能。

下面我将为您提供一个经典、灵活且高效的数据库设计方案,并解释每个表的作用和关联关系。


核心设计理念

采用“SPU + SKU”的模型,并将属性与商品解耦,通过关联表来管理,以实现最大的灵活性。

  1. SPU (Standard Product Unit):标准化产品单元。定义一组商品的共享属性(如名称、描述、品牌、分类等)。例如:iPhone 15 就是一个SPU。

  2. 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选择器。


设计要点与考虑

  1. 灵活性:属性可以动态增删,并能被不同分类的商品复用。

  2. 性能

    • 冗余字段:在sku_sale_attr_valuespu_attr_value中冗余存储了attr_valuespu_id,极大地提高了查询速度,是常见的空间换时间的优化策略。

    • 索引:在所有常用的查询字段(如spu_id, sku_code, category_id)上建立索引。

  3. 库存管理:库存数量(stock)保存在sku表,是原子操作的最小单位。所有库存操作(扣减、增加)都必须基于SKU ID进行。

  4. SKU编码sku_code需要保证全局唯一,通常有固定的生成规则(如:SPU编码 + 属性值编码的某种组合)。

  5. 扩展考虑

    • 价格体系:如果价格策略复杂(如会员价、活动价),需要单独设计价格表

    • 图片 gallery:如果需要多个SKU图片,可以设计sku_image表。

    • 条形码:可以在sku表中增加barcode字段。

这个设计经过了大量电商项目的验证,在灵活性和性能之间取得了很好的平衡,可以作为您系统设计的坚实基础。

开启新对话

内容


评论