Lei Zhang

时光已逝永不回,
往事只能回味。
... ...
春风又吹红了花蕊,
你已经也添了新岁。

▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 96%



商品多规格多属性模型设计思路

2018-03-05 » MySQL / Django , Tutorial

区分货品(SPU)和商品(SKU)

SPU = Standard Product Unit (标准化产品单元):

一件衬衣,它就是一个 SPU,此外它不具有库存、价格等因素,它仅仅是众多款衬衣抽象出来了一个货品。

SKU=stock keeping unit(库存量单位):

对于服装来讲,它应该会有尺寸、颜色等规格,以及该规格下对应的属性,如:XL、L、红色、白色等等,不同属性组合所表示的就是一个 SKU,如 尺寸:XL、颜色:红色,它会有库存、价格,用户真正下单所购买的也是 SKU,而不是 SPU。

SPU是标准化产品单元,区分品种;SKU是库存量单位,区分单品;SPU 与 SKU 是 ONE-TO-MANY 的关系。

规格模型

SPU 是一个抽象出来的货品,货品再向上可以抽象为一个分类。如衬衣,它的规格尺寸、颜色等,是衬衣这个 SPU 所共有的,衬衣再网上可以归类为 服装 分类,服装这个分类可以包括多种 SPU,如衬衣、牛仔裤、T恤等等。

那么我们在创建一个分类时,就可以针对某个分类,如服装,定义好服装下面的公共规格,如:尺寸、颜色、尺码等等。

再创建一个货品时,便可将该分类下的规格,选择一个或者多个与货品形成绑定关系。

分类与规格:ONE-TO-MANY;

分类与货品:ONE-TO-MANY;

规格与货品:MANY-TO-MANY;

表结构设计

1. 数据表列表:

(分类)category

(规格)attribute

(属性)value

(货品)product

(商品)sku

2. 数据表关系:

分类、规格:ONE-TO-MANY

规格、属性:ONE-TO-MANY

分类、货品:ONE-TO-MANY

货品、商品:ONE-TO-MANY

货品、规格:MANY-TO-MANY

货品、属性:MANY-TO-MANY

商品、属性:MANY-TO-MANY

3. 简单的表结构图:

数据结构

现在我们设计好了模型,在进行前后端交互时,如何组织数据结构,利于前端渲染数据呢?我们在京东上找到一个带有多规格的商品,左边是规格(attribute)名称,右边是不同规格下的属性值(value),如图:

首先,前端需要将该货品(SPU)下的全部规格及属性渲染出来,再根据用户所组合的属性来显示对应商品(SKU)的价格、库存等信息。那么我们大致的数据结构可以组装成这样:

渲染方式

前端通过 detail 显示货品的公共信息,通过 attrs 将规格及规格的属性渲染至页面中,用户在每次勾选属性时,拼接 attr_idvalue_id,在 skus.combines 中查询是否存在该组合,若存在,则显示当前 skus 的价格、库存等等信息。

同时,我们也可以将 sku_code 放在商品详情的 url 参数中,前端获取到 sku_code 后,通过 sku_code 也可以逆向查询到当前的 attributevalue 组合方式,直接将符合 sku_code 的属性渲染为 已选中 的高亮样式。

查询流程

只是简单的描述根据上述表结构,如何通过 product_id 进行查询并将查询结构封装为上图所示的数据结构,可能并非最优查询方式,这里我直接使用 Django 的 ORM 进行查询。

1. 封装 detail & attrs:

根据 product_id 可以直接在 product 表中查询到货品的基本信息,并将 product.id、product.name、product.desc 封装进 detail 属性中;

由于 product 与 attribute 及 value 均为 MANY-TO-MANY 的关系,我们可以通过 product_attribute 表、product_value 表获取到该 product 所关联全部的 attributes & values。

由于 attribute 与 value 是 ONE-TO-MANY 的关系,那么只需要循环 attributes,通过判断 value.attribute_id 与当前的 attribute.id 是否相等,便能将 attribute 与 value 组合封装。

2. 封装 skus

由于 product 和 sku 是 ONE-TO-MANY,通过 product,能直接获取到其全部的 skus。

接下来,sku 与 value 是 MANY-TO-MANY 的关系,便能获取到该 sku 下的全部 value,并通过 value 查询到其对应的 attribute_id,然后封装进每个 sku 的 combines 中。

完整查询示例

表会比较冗余,因为在创建或修改货品的规格时,需要同时操作 product_attribute、product_value、sku、sku_value 四张表。

其实 product_attribute、product_value 可以移除,通过 sku 及 sku_value 也能查询到该 product 所涵盖的 attribute & value。

展开选填信息