PHP 产品库 SPU、SKU 如何设计?

我现在的系统的产品库设计真是渣渣,产品的规格、颜色、型号都是固定的字段;导致同一个产品不同颜色就要录N个产品,比如一个苹果6,就要分别录N样颜色产品(苹果6金色、银色、黑色)。

看了网上SPUSKU的概念后感觉应该是完美解决方案了。

由于菜,所以请各位大神给讲讲这块怎么设计的好。给一些思路,或者有好的开源项目我去看看。

阅读 19.2k
5 个回答

2017-03-14 更新:
商城 商品模块 数据库 表设计 (新思路)

小米MIX是一个SPU(Standard Product Unit).
小米MIX标准版(4GB内存+128GB容量)小米MIX尊享版(6GB内存+256GB容量)
则是两个不同的SKU(Stock Keeping Unit).
可见不同SKU的价格,规格,库存是不同的,所以不同的SKU应该采用不同的商品编号.
比如神舟的"K610D"这款笔记本,规格有很多.
每种规格都有自己的商品编号/价格/规格/库存:
http://item.jd.com/1603013.html
http://item.jd.com/1939941.html

建表方案:

商品表(商品ID,商品名)
属性表(属性ID,属性名)
商品对应的属性表(商品ID,属性ID,属性值)

CREATE TABLE `df_goods` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

CREATE TABLE `df_attr` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

CREATE TABLE `df_relation_goods_attr` (
    `goods_id` int(10) unsigned NOT NULL,
    `attr_id` int(10) unsigned NOT NULL,
    `value`   varchar(255) NOT NULL DEFAULT '',
    UNIQUE KEY (`goods_id`, `attr_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

获取编号为1的产品具有的属性名和属性值:

INSERT INTO df_goods VALUES(1,'小米MIX标准版');
INSERT INTO df_goods VALUES(2,'小米MIX尊享版');
INSERT INTO df_attr  VALUES(1,'内存');
INSERT INTO df_attr  VALUES(2,'存储');
INSERT INTO df_relation_goods_attr  VALUES(1,1,'4GB');
INSERT INTO df_relation_goods_attr  VALUES(1,2,'128GB');
INSERT INTO df_relation_goods_attr  VALUES(2,1,'6GB');
INSERT INTO df_relation_goods_attr  VALUES(2,2,'256GB');

select df_attr.name, df_relation_goods_attr.value
from df_relation_goods_attr
join df_goods on df_relation_goods_attr.goods_id = df_goods.id
join df_attr  on df_relation_goods_attr.attr_id  = df_attr.id
where df_goods.id = 1
结果:
name  value     
内存  4GB
存储  128GB

可以把表设计如下:

商品表

商品 id 商品名称
1 iPhone
2 黄瓜

商品属性表

商品 id 规格 颜色 价格
1 16g 白色 4999
1 32g 白色 5499
2 1

对于你现在自己练手项目,最适用就是这种设计了.
不过此种设计针对商品的属性一定或少的情况下适用,如果属性较多,那么就要增加属性字段,而且有的商品未必用到了这个属性,造成浪费,导致属性表不变扩大.例如商品2黄瓜.
可以变成如下设计:

属性表

属性 id 属性名称
1 规格
2 颜色
3 价格

商品种类表

种类 id 商品 id
a 1
b 1
c 2

商品属性表

商品种类 id 属性 id 属性值
a 1 16g
a 2 白色
a 3 4999
b 1 32g
b 2 白色
b 3 4999
c 4 上海

设计如上,商品黄瓜的属性只会产生一条数据.

正好在做电商系统,我的思路是这样的:
三张表,分别是商品表sku表sku属性表
商品表对sku表为一对多的关系,sku表主要存储属性对应的价格、库存等。
sku表对sku属性表也是一对多的关系,sku属性表储存的就是颜色、尺寸这些字段。

大概就是这么个意思

大体像小小木头说的这样,可能还要补充个规格表来存储规格的信息。

其实没必要这么设置, 商品表设置两个表, 一个主表good_common, 一个商品表good表,在主表中 你设置添加两个字段 一个是规格名字;spec_name 一个是规格值;spec_value, 吧商品选中的规格和选中的规格值 都保存进去, 储层为序列化值就好了, 这个是主表的入库, 主表入库之后,得到刚刚入库的主表中的good_commid, 在根据表单的这个规格循环下, array (size=4)
'i_5860' =>

array (size=10)
  'goods_id' => string '34280' (length=5)
  'color' => string '58' (length=2)
  'sp_value' => 
    array (size=2)
      58 => string '白色' (length=6)
      60 => string '白色' (length=6)
  'first_price' => string '558.00' (length=6)
  'second_price' => string '560.00' (length=6)
  'marketprice' => string '568.00' (length=6)
  'price' => string '568.00' (length=6)
  'stock' => string '98' (length=2)
  'alarm' => string '0' (length=1)
  'sku' => string '' (length=0)

'i_5861' =>

array (size=10)
  'goods_id' => string '' (length=0)
  'color' => string '58' (length=2)
  'sp_value' => 
    array (size=2)
      58 => string '白色' (length=6)
      61 => string '黑色' (length=6)
  'first_price' => string '' (length=0)
  'second_price' => string '' (length=0)
  'marketprice' => string '568.00' (length=6)
  'price' => string '568.00' (length=6)
  'stock' => string '12' (length=2)
  'alarm' => string '0' (length=1)
  'sku' => string '' (length=0)

'i_5960' =>

array (size=10)
  'goods_id' => string '34281' (length=5)
  'color' => string '59' (length=2)
  'sp_value' => 
    array (size=2)
      59 => string '黑色' (length=6)
      60 => string '白色' (length=6)
  'first_price' => string '558.00' (length=6)
  'second_price' => string '560.00' (length=6)
  'marketprice' => string '568.00' (length=6)
  'price' => string '568.00' (length=6)
  'stock' => string '99' (length=2)
  'alarm' => string '0' (length=1)
  'sku' => string '' (length=0)

'i_5961' =>

array (size=10)
  'goods_id' => string '' (length=0)
  'color' => string '59' (length=2)
  'sp_value' => 
    array (size=2)
      59 => string '黑色' (length=6)
      61 => string '黑色' (length=6)
  'first_price' => string '' (length=0)
  'second_price' => string '' (length=0)
  'marketprice' => string '568.00' (length=6)
  'price' => string '568.00' (length=6)
  'stock' => string '14' (length=2)
  'alarm' => string '0' (length=1)
  'sku' => string '' (length=0)
  类似这种数据格式, 循环插入商品表就好了, 但是每个的价格可能是不一样的,其他的应该都是一样的吧,
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题