一, 总体设计
为什么采用中台架构前几篇已经说明了, 这里就介绍一下基础层和平台层的功能.
1. 基础层
发布, 编辑, 上架, 下架这些功能大家应该比较熟悉.
审核: 是否需要审核通过才允许上架
打标: 对商品进行标记, 例如参加某种活动
Sku 管理: 商品和 sku 关系
关联关系: 前后端商品关联关系, 组合商品关联关系等
前后端商品: 前端商品面向用户, 后端商品面向仓库
类目: 商品类目, 前后端类目
属性: 商品属性, 类目属性等等
2. 平台层
商品管理: 商品的基本操作
商品收藏: 管理用户收藏的商品
商品快照: 保存商品编辑的每一个快照版本
活动打标: 根据不同的活动映射到商品属性上不同标记
销量管理: 商品的销量统计, 以及排序操作
浏览历史: 用户浏览记录
搜索: 不同维度对商品的搜索
二, 概念定义
1. Item-sku
Item 代表产品 sku 代表商品
举例: item 对应苹果 7 手机 但苹果 7 有黑色, 白色 则 sku 对应黑色的苹果 7 手机
对应关系如下:
2. 前后端商品
前端商品: 面向用户的, 在商城展示销售的, 它是一个虚拟的概念.
后端商品: 面向仓库实体商品的, 比如一台电脑就创建一个后端商品. 它和仓库有着紧密的关系, 同步库存, 入库出库等操作都要同步到该商品信息.
前端商品和后端商品有个映射关系, 比如前端商品为电脑, 则后端商品会对应一个电脑.
后端组合商品: 有些商品是可以单个售卖, 也可以打包售卖, 比如电脑套装优惠, 这个套装就是一个组合商品 A, 他是由电脑 B, 鼠标 C, 键盘 D 组成.
所以这里就有一个映射关系 A->(1B,1C,1D). 此时如果需要在商城售卖, 则可以创建一个前端商品和 A 进行关联.
3. 关联关系
这里关联关系就包括: 前端商品和后端商品的映射关系, 后端组合商品和单个商品的关系. 根据这个关系可以确定该商品在哪些仓库有库存, 该发货几个等等.
4. 商品快照
商品每次编辑都会保存一份快照, 一来可以记录操作日志, 二来可以追溯, 比如订单会存一个快照商品版本, 根据该版本找到下单当时的商品信息.
5. 商品打标
打标其实就是一个标记, 比如一个商品参加的十几个活动, 那么怎么在商品上保存, 我们可以使用一个 long 型字段 flag 来保存, long 是 64 位, 每一位代表一种类型的活动, 0 代表否, 1 代表是, 通过对 flag 进行二进制操作即可完成活动信息更新.
6. 类目
类目也分为前后端类目, 前端类目就是面向用户, 具有导航功能, 而且易变.
后端类目是和商品直接关联, 很稳定. 前后端类目有映射关系.
7. 属性
商品关联的属性, 举例: 黑色苹果 7 手机, 他具有属性为颜色, 属性值为黑色.
三, 技术设计
1. 关系图
2. 商品关键字段介绍
商品表都是基于分库分表的设计.
category_id: 商品和类目是一对一的关系, 创建商品的时候需要首先获取到商品所属类目. 判断该类目下商品发布是否需要审核, 以及商品必须要填充该类目下关联的属性并保存到商品上.
item_pattern: 商品形态: 包括实物商品, 虚拟商品, 服务商品, 为什么要有这个字段, 因为实物商品需要关联仓库实物商品; 虚拟商品不需要关联, 比如电子书, 视频等等; 服务商品作为另外一种特殊处理方式, 比如三年保修, 送货上门等都是作为一种服务, 我们把它抽象成服务商品, 在下单时一同加入订单中, 这样做的好处在于易于扩展.
item_type: 商品类型: 包括前端商品和后端商品; 或者组合商品, 或者扩展的商品类型.
shop_id: 归属的店铺
selle_id+item_code: 商家 id 和商家编码, 如果是商家自己 erp 系统导入的商品, 则这两个字段是唯一的, 能唯一确定商家系统的商品.
flag: 标记位, 进行二进制打标操作.
biz_type: 所属业务平台, 根据该字段进行不同业务间的数据隔离.
feature: 扩展字段, 将商品属性存在里面, 也可存储未来新加的信息而无需改表结构.
3. 商品历史表 Item_history 设计
历史表就是已经删除了的商品数据表, 那为什么要把删除的数据保存下来, 这就是电商系统的设计原则, 任何表的数据只逻辑删除, 不进行物理删除. 所以很多表都会加上 is_delete 字段标记是否被删除.
但是商品表为什么要新建一张表, 这里有两点, 1)商品表中有唯一键约束,(seller_id,item_code), 如果删除了放在原表, 商家再次同步该商品时, 因为这两个字段相同, 会影响唯一键约束, 但又不能真正删除, 所以就将数据移至历史表. 2)商品表数据日积月累会越来越庞大, 将删除的数据迁出有利于提高原表的性能.
4. 商品快照设计
商品作为电商交易中的对象, 对其任何的改动都至关重要, 所以存储快照一方面是把每次的更改记录都保存下来. 另一方面是存在类似于交易订单的场景, 需要当时商品的信息, 以便处理投诉, 维权.
那么快照数据更加庞大, 因为每一次的改动都会生成一份数据, 所以不能存在数据库, 而是采用外部存储. 查询的时候需要 itemId+snapshotVersion, 商品 id 和快照版本进行查询.
5. 商品打标设计
首先定义一个活动类型枚举类, 说明每一位代表什么活动. 其他类型也可以, 反正就是标记该商品具有某种属性.
假如 flag=0; 现在商品参加某个活动, flag 第三位代表该活动, 则打标过程为;
flag=flag | (1 << 2)
去标同样的逻辑.
6. 商品扩展字段设计
不仅是商品表, 在工作中我们会经常遇到, 在需求不断迭代的过程中, 肯定会有添加字段的需求, 但如果我们添加的字段都不是关键字段的话(不用于检索), 比如商品表如果后端商品现在需要存储长宽高, 质量, 以及一些产地等信息, 我们就可以通过扩展字段的方式解决, 而且还免去了对线上表加列的操作. 扩展字段 feature 其实就是 JSON 格式的字符串, 预留一定长度, 待后面有需求在往里面加键值对.
比如说加之前是这样存的:
{"length":10,"width":12,"height":20}
加了产地后就变为
{"length":10,"width":12,"height":20,"region":"HZ"}
但更新的时候一定注意要带版本更新, 否则并发情况将会发生数据覆盖. 这也是另外一个设计原则, 数据库所有表都要加 version 字段的原因: 数据更新乐观锁控制.
7. 商品销量统计 & 排序
销量其实不是作为商品本身的一个属性, 因为销量是根据交易订单成交量来动态计算出来的, 但是一般电商网站都会有根据销量排序的需求, 那这个怎么实现呢. 肯定是搜索引擎来做, 因为搜索条件太多, 排序条件太多, 数据库索引也支持不了各种组合查询, 排序. 所以我们就根据业务需求, 一般销量一天统计一次就满足需求了. 在商品索引中添加一个销量字段, 每天定时任务从订单里面统计销量, 然后再以消息的方式, 推送到搜索引擎, 搜索排序的时候搜索引擎就能帮我们实现这个功能.
8. 商品类目设计
类目设计将在后续文章详细介绍. 包括前台类目, 后台类目, 类目树构建, 类目缓存设计, 类目属性等等.
9. 商品搜索设计
搜索设计将在后续文章详细介绍. 搜索设计包括搜索引擎选型, 存储结构设计, 索引构建, 搜索, 以及通用搜索框架等等.
四, 总结
本文介绍了商品系统分层设计, 以及每一层对应的功能和功能设计. 后续还会对商品系统中设计要点, 细节进行详细介绍, 比如类目, 搜索. 此外, 在实现中还涉及了许多中间件的封装使用, 所以后续还会对通用组件 (通用搜索框架, 消息框架) 进行介绍.
来源: https://juejin.im/post/5bed5dcd6fb9a04a0d566bbf