Stay hungry, Stay foolish

0%

浅淡商品sku设计

背景

去年接触电子商务的研发,才发觉平日里网上购物的一些功能用着特别的舒服,而背后的细节,十分的不容易。比如说商品及属性,初期没有一个好的规划,到后来举步为艰,只能重构。而网上这方面的资料又比较的少,所以折腾一番,决定写一些心得出来,希望能抛砖引玉。文中不到之处,还望各位看官不吝给予指正。

名词解释

  • sku

Stock Keeping Unit 库存量单位,又称最小库存单元。这个名词的设计是为了方便库存的精确管理。一个sku通常是多个属性的组合。
通常说的SKU指的是商品SKU,即一款商品的某些属性组成的单个商品。

  • sku属性

可以把一款商品进行拆分的属性。比如衣服,颜色和尺码便是sku属性,其它如面料等就是普通属性。

  • 搜索sku属性

在搜索页,红色的衣服,尺码的不同,会显示多个,为了更友好的聚合展示,把如颜色这种属性定义为搜索 SKU属性。

需求

电子商务网站,商品管理,要求满足:

  • 前台商品终端页,同一款商品通过不同sku属性关联到一起;
  • 搜索页面,搜索sku属性的全部显示出来,能按属性进行筛选。

举个例子:

一件衣服,有两个sku属性(颜色、尺码),颜色是搜索sku属性,尺码是普通sku属性。

现在有2个颜色(红、蓝)和2个尺码(m,xl),可以生成四个sku:sku001(红,m),sku002(红,xl)、sku003(蓝色、m)、sku004(蓝色、xl)。

那么,在商品终端页,会显示四个属性,对应各自的链接;该衣服的搜索结果页,只会显示红色、蓝色两件,可以根据四个属性进行筛选。

常见设计方式

先说一下电商系统进行SKU管理的一般思路:

  • 一个商品对应多个属性(淘宝)
  • 一个商品对应一个sku(京东……)

第二种可以有两种实现

  • 一个商品表,对应多个sku表
  • 一个商品对应一个SKU,后台采取复制进行管理

第一版设计

设计思想:

每一个商品对应一组sku,通过复制产生同类商品,同款商品进行关联后,在商品关联表里生成一条记录,商品管理界面有批量管理功能。

第一版的数据表是这样设计的(我参与的时候已经设计好了的):

这个对于需求1没有问题,对于需求2,就要做很多的判断:

  • 有搜索SKU
  • 没有搜索SKU,有普通SKU
  • 没有SKU属性

由于需要满足于不同的搜索条件而写出来的SQL太过于复杂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
select min(`goods`.`sku_id`) as `minID` from (
`goods ` left join (
`goods_attribute` join `attribute` on (
(`goods_attribute`.`attribute_id` = `attribute`.`id`) and
( `attribute`.type = 2)
)
) on (
`goods_attribute`.`sku_id` = `goods`.`sku_id`
)
) group by `goods`.`sn`, (
case when isnull(`goods_attribute`.`attribute_id`)
then `goods`.`sku_id`
else `goods_attribute`.`attribute_id`
end
), (case when `goods_attribute`.`value`
then `goods`.`sku_id`
else `goods_attribute`.`value`
end
);

第二版设计

设计思想:

在查询了一些资料后开始对第一版设计进行反思:前一版设计主要的原因在于商品的聚合,如果反过来思考会如何呢?

有相同sn的是一款商品(group sn即可实现),接下来考虑的是如何把这个来”拆分”开呢?

加字段(group_sn)

字段里存放什么呢?

关键属性值的ID

恩,这样就可以根据sn和这个字段实现了(group by sn, group_sn),可不可以用一个字段来实现呢?

让我想想,关键属性值的ID串前再加个sn

很好,这样能过group group_sn来实现了,而且可以用group sn来满足完全去重的需求

第二版设计的数据表:

这次改版后不仅查询上提升了N个数量级,表的设计与SQL看着都清爽多了。

1
2
3
4
5
6
7
8
9
10
select min(`goods`.`sku_id`) as `minID` from (`goods ` left join (
`goods_attribute` join `category_attribute` on (
(`goods_attribute`.`category_attribute_id` =
`category_attribute `.`id`) and
( `attribute`.type = 2)
)
) on (
`goods_attribute`.`sku_id` = `goods`.`sku_id`
)
) group by `goods`.`group_sn`

这一版还有什么问题呢?

后台操作人员认为复制这样的操作太过繁琐

那么,就看看前面提到的第二种设计吧

第二种设计

设计思想:

商品进行属性的操作时,根据sku属性在goods_sku表中生成记录。

题后话

对于表的设计,到这里就结束了。有的同学可能会问设计好了,如何搜索呢,如果想了解这部分,可以搜一下中文分词、全文检索的资料及工具。笔者用的是sphinx/coreseek,本博中有一篇sphinx安装的文档可供参考

电子商务这个行业里有很多东西值得去深入挖掘。就拿商品的设计与管理,也不是一篇两篇文章能写的完的。本文也只能从笔者接触到了几种设计方式去分析一下,写的实在是太粗(比如最后一张图,应该有一个与goods表对应的普通属性表),还望各位看观能谅解!

欢迎留言/Email交流~

参考资料

据说打赏我的人,代码没有BUG