欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

商品表结构分析

程序员文章站 2022-07-14 20:59:35
...

引言

先引入两个概念:

SPU:Standard Product Unit (标准产品单位) ,一组具有共同属性的商品集

SKU:Stock Keeping Unit(库存量单位),SPU商品集因具体特性不同而细分的每个商品
商品表结构分析

  • 所有sku共享的规格属性(称为全局属性)
  • 每个sku不同的规格属性(称为特有属性)

1 表结构分析

      手机的参数大多是颜色、版本、内存等等,而空调的参数大多都是匹数、功率等,因此设计商品参数表时不应该基于商品去设计,而应该基于商品类别去设计表结构
      所以一个分类下有一套规格参数,但是相同分类下的商品虽然规格参数相同,但是规格参数的值不同,比如都是手机,一个手机品牌参数的值是“小米”,另一个手机品牌参数的值是“苹果”。
      要想简化这件事,key(参数)和值(参数的值)分开保存。key跟商品分类绑定,值跟商品绑定。比如,颜色、版本、内存等参数跟手机类别绑定,具体一个手机的品牌是什么,内存多大等值跟商品绑定。
商品表结构分析
但是也不能一个类别一张表,这样就太多了,因此这样不现实!
设计如下:

  • 规格组表tb_spec_group
    商品表结构分析

商品表结构分析

  • 规格参数表tb_spec_param
    商品表结构分析

通用属性

用一个布尔类型字段来标记是否为通用:

  • generic来标记是否为通用属性:
    • true:代表通用属性
    • false:代表sku特有属性

搜索过滤

与搜索相关的有两个字段:

  • searching:标记是否用作过滤
    • true:用于过滤搜索
    • false:不用于过滤
  • segments:某些数值类型的参数,在搜索时需要按区间划分,这里提前确定好划分区间
    • 比如电池容量,0-2000mAh,2000mAh-3000mAh,3000mAh-4000mAh

数值类型

某些规格参数可能为数值类型,这样的数据才需要划分区间,我们有两个字段来描述:

  • numberic:是否为数值类型
    • true:数值类型
    • false:不是数值类型
  • unit:参数的单位

2 从面向对象的角度分析

既然现在要表示规格参数的key,暂时不考虑值,那么这些key用java语言如何描述呢?

组该如何描述?要把组当成一类事物,对他们进行抽象,找到其中的共同特征,比如每个组都有一个名字,只不过第一个组叫 主体,第二个组叫 基本信息,以此类推,因此,组就要有一个字段叫name来抽象表示这个组的名字,除此之外,每个组都要有一个id。每一个组内都有很多参数,比如 主体 这一组下就有 型号、入网年份、上市年份等参数,因此还要有一个集合字段params,存放这些参数。

注:图画的有点问题,绿色框不应该框值,应该框中间的key。
商品表结构分析
此外List<Param> params中也可以抽象,依旧是每个参数都有nameid,此外还需要一个组ID来关联组表,说明这些参数是属于哪一个组下面的,这样就把group表param表关联了起来。既然思考到这一步,想到互相关联,那么group表中也可以添加一个字段categoryId来关联商品类别。param表中可以加入是否为数值类型的字段、该参数是否可搜索字段等等。

3 spu表的数据结构

商品表结构分析
      为了不影响查询效率,基于此,我们做了表的垂直拆分,将SPU的详情放到了另一张表:tb_spu_detail

  • 垂直拆分,一张表字段过多,拆成两张表来存
  • 水平拆分,一张表数据太多,拆成两张表来存

      更常用的是垂直拆分,因为水平表拆分对增删改查操作很不友好,比如排序,排序只能完成一张表中数据的排序,但是现在有很多中间件来帮助实现。

根据前面的分析有:

  • SPU中保存通用的规格参数信息。
  • SKU中保存特有规格参数。

      当时我们的规格参数表没有区分哪些是特有属性,哪些是通用属性,但还好我们的参数表中有一个字段是generic,是一个布尔值,来表明这个参数是否为通用属性。那么我们的表该如何设计呢?


      首先是generic_spec,其中保存通用规格参数信息的值,这里为了方便查询,使用了json格式,并且跟param表一一对应(左为param表,右为generic_spec字段):商品表结构分析

  • key:对应的规格参数的tb_spec_param的id
  • value:对应规格参数的值

其次是special_spec字段,从数据库中取一个来看:
商品表结构分析
转成json格式方便查看,如下:
商品表结构分析

  • key:规格参数id
  • value:spu属性的数组

那么问题来:特有规格参数应该在sku中记录才对,为什么在spu中也要记录一份?

因为我们有时候需要把所有规格参数都查询出来(比如如下商品详情界面),而不是只查询1个sku的属性。比如,商品详情页展示可选的规格参数时:
商品表结构分析

4 sku表的数据结构

      sku又分成了两张表,一张tb_sku表,一张tb_stock表,为什么把库存单单拿出来另建一张表呢,因为一个商品读写最频繁的就是库存数据,而颜色、内存等一般不会改变,以读为主,因此我们将两张表分离,读写不会干扰。

sku表中部分字段的说明:
商品表结构分析
indexes字段:

在SPU表中,已经对特有规格参数及可选项进行了保存,结构如下:

{
    "4": [
        "香槟金",
        "樱花粉",
        "磨砂黑"
    ],
    "12": [
        "2GB",
        "3GB"
    ],
    "13": [
        "16GB",
        "32GB"
    ]
}

这些特有属性如果排列组合,会产生12个不同的SKU,而不同的SKU,其属性就是上面备选项中的一个。

比如:

  • 红米4X,香槟金,2GB内存,16GB存储
  • 红米4X,磨砂黑,2GB内存,32GB存储

如果我们记录下角标,就是这样:

  • 红米4X,0,0,0
  • 红米4X,2,0,1

      既然如此,我们是不是可以将不同角标串联起来,作为spu下不同sku的标示。这就是我们的indexes字段。

这个设计在商品详情页会特别有用:
商品表结构分析
当用户点击选中一个特有属性,就能根据 角标快速定位到sku。


own_spec字段:
看结构:

{
	"4":"香槟金",
	"12":"2GB",
	"13":"16GB"
}

保存的是特有属性的键值对。

SPU中保存的是可选项,但不确定具体的值,而SKU中的保存的就是具体的值