电商产品体系非常复杂,很值得深入研究,我准备集中一段时间对这个产品体系进行设计拆解。商品中心的拆解是此系列的第一篇。
电商产品架构
说到电商,作为消费者可能有比较直观的体感,在网上商场里面的购物流程大概如下:
浏览商品—>选购商品—>支付下单—>坐等物流送货上门—>评价商品—>订单完成。
这里面每一个环节都涉及到1个或多个系统在背后运行支撑,非常复杂。
如果你在淘宝开过店,就会知道淘宝后台同样存在着一套非常复杂的商家支撑系统,支持着商品的上架发布、库存管理、促销活动管理、物流管理、订单管理、评价管理等一系列后台操作,这些操作都是相互独立又互相衔接的独立系统在支撑。
从消费者、商家的角度来进行粗犷的感知,我们就会知道电商体系的复杂度可想而知,根据以上的场景,我们可以粗略地画出电商的产品架构:
电商产品架构
商品的几个概念
电商产品形态的目标,本质上其实就是卖货。为了提升卖货效率,电商产品主要围绕着3方面的工作展开:
- 信息流:提升信息流动的效率,让商户方便的发布商品信息,用户方便的寻找商品信息。
- 资金流:提升资金流动的效率,让用户方便的下单支付,商户更方便的结算资金。
- 物流: 提升实体商品流动的效率,让商户更快的从商家流动到用户手中。
商品中心 是电商产品的信息化基础,商品信息是信息流的重中之重,如何让商户将商品信息格式化,商户可以方便的进行发布管理,用户可以便捷搜索浏览,是商品信息化的核心。
电商系统经过了这么多年的发展,已经形成了一套比较成熟的商品信息模型。在进行系统设计拆解之前,有必要对一些概念进行讲解。
SPU & SKU
概念简写 全称 SPU Standard Product Unit SKU Stock Keeping Unit
先来看下定义:
SPU:
标准化产品单元,是商品信息聚合的最小单位。是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。通俗点讲,属性值、特性相同的商品就可以称为一个SPU。
SKU:
库存量单位,即库存进出计量的单位,可以是以件、盒、托盘等为单位。SKU是物理上不可分割的最小存货单元,在使用时要根据不同业态,不同管理模式来处理。
概念看完以后,似懂非懂。
看个例子吧。
iPhone X —— SPU iPhone X 土豪金色 128g —— SKU
iPhone X就是一个SPU,它集合了“电子产品-手机-苹果手机-iPhone X” 下的所有商品属性信息。只要说是iPhone X,人们就知道是这个型号的手机。
大家想想平时我们讨论手机的场景,其实说的都是SPU,比如说:
A:听说你买了新的手机,是什么? B:华为Pro30。你现在用的是什么? A:我还在用iPhone X 呢。 你看,这个场景中说的都是SPU。
SPU是定位到产品的概念,但它和产品细节无关。但实际上,我们在购买商品的时候,单凭SPU是不够的,还需要更多的信息来精确到可购买单元。
在Apple Store购买iPhone时,我们可以说:“我想买iPhone X。”
接着导购一定会问你:你要的是什么颜色的?内存多少?
所以,在实际的交易行为中,必须要有一个最小购买单位来对应一件商品——这就是SKU,在商家端也称库存单位。
属性
从SPU&SKU的概念可知,其实他们之间是存在联系的。他们的关系可以如图所示:
模型关系图
它们之间的关系可以用一句话总结:
SPU 叠加上销售属性后,就得到了SKU。
举个例子,
iPhone X是SKU, 叠加了土豪金(颜色属性)、128G(容量属性)以后,它就变成了SPU。
后台类目 & 前台类目
08年的时候,电商产品的类目划分还并没有区分前后台,但是商品类目的设计革新已经迫在眉睫:
1、商品库越来越庞大,对应的类目级别越来越深,商家发布商品,用户查看商品的难度越来越大。
2、电商平台的营销活动日益增多,商品类目的变化需求极大,但是类目维护成本高昂
淘宝的产品经理在去逛沃尔玛超市的过程中得到了灵感,他发现传统超市的分类逻辑可以很好的被电商产品借鉴:
大超市里的商品,在货架上的陈列方式都是经常变来变去的,随着季节、特殊节日、销售状况等因素的变化,商品的陈列方式也会经常做出调整。
但大超市还有一个地方是仓库,仓库里的商品摆放是相对固定的,食品就在食品区,洗护就在洗护区。所以说,超市里的商品其实是放在两个地方——后台仓库和前台货架,使用的分类方法也是截然不同的。
从这里他受到启发,想出了“前台类目+后台类目”的设计方案——把一个产品一分为二,一个满足买家,一个满足卖家,也就是:
卖家通过后台类目发布商品,买家通过前台类目选购商品。
原来的类目变成了后台类目树,另外再建一个前台类目树,然后把前台类目树的叶子类目去和后台类目通过映射关系关联起来。任何一个前台类目的叶子类目,都可以对应任何一个或多个后台类目,且不一定是后台叶子类目。
现在,类目设计的前后台分离已经成为电商产品的标配。
附上天猫商城和小米商城的前台类目:
天猫商城的前台类目,3层结构
小米商城的前台类目,2层结构
设计拆解
系统设计概览
任何脱离了业务场景的设计,都是耍流氓。商品的模型从直觉上来可以很简单,就是对商品信息进行维护就可以了。但是从上文中可知,信息维护仅仅完成了第一步,如何让信息流动更高效,如何对千万级甚至亿级的商品库进行快速维护、高效检索,对商品信息分类的需求是自然发生的。基于上文中商品的核心概念,我们可以得到商品中心的系统概览图:
商品中心概览图
模型设计
业务场景清晰了,模型设计是水到渠成的事情。从模型关系图可知,商品中心的核心模型包括
在这里,我直接放出模型设计:
模型设计
上图中模型设计仅包含后台核心模型设计(抓大放小),前台类目的设计比较灵活多变,可以直接复用后台类目的设计思路,也可以新起一套,按照商城前端UI呈现的需求进行设计。附上完整的代码定义:
// 品牌表 brand
{
"id": "主键ID",
"name": "品牌名字",
"icon": "品牌图标",
"desc": "描述",
"status": "状态:-1-已删除,0-禁用,1-正常," }
// 类目表(后台) back_category
{
"id": "主键ID",
"pid": "父ID",
"name": "类目名字",
"desc": "描述",
"leaf": "是否为叶子节点,1-是,0-否",
"level": "层级",
"path": "类目路径",
"status": "状态:-1-已删除,0-禁用,1-正常," }
// 类目表(前台) front_category , 一般两级就够了
{
"id": "主键ID",
"pid": "父ID",
"name": "类目名字",
"desc": "描述",
"leaf": "是否为叶子节点,1-是,0-否",
"level": "层级",
"path": "类目路径",
"status": "状态:-1-已删除,0-禁用,1-正常," }
// 属性定义表 attr
{
"id": "主键ID",
"name": "属性名字",
"desc": "属性描述",
"status": "状态:-1-已删除,0-禁用,1-正常," }
// 属性值表 attr_val
{
"id": "主键ID",
"attrId": "属性id",
"valName": "属性值名称(用于展示)",
"val": "属性值(用于存储)",
"status": "状态:-1-已删除,0-禁用,1-正常," }
//标准产品单元 spu
{
"id": "主键ID",
"name": "spu名字",
"desc": "spu描述",
"brandId": "归属品牌",
"categoryId": "归属类目",
"unit": "单位",
"url": "产品介绍链接",
"price": "价格",
"showPrice": "展示价格",
"status": "状态:-1-已删除,0-禁用,1-正常," }
//库存单元 sku
{
"id": "主键ID",
"spuId": "SPU ID",
"name": "名字",
"desc": "描述",
"brandId": "归属品牌",
"categoryId": "归属类目",
"unit": "单位",
"url": "产品介绍链接",
"price": "价格",
"showPrice": "展示价格",
"attrs": "属性值集合[{attrId:'', attrName:'', val:'', valName:''},{attrId:'', attrName:'', val:'', valName:''}]",
"status": "状态:-1-已删除,0-禁用,1-正常," }
// 关联关系(后台) sku_map
{
"id": "主键ID",
"spuId": "SPU ID",
"skuId": "SKU ID",
"categoryId": "类目ID(叶子类目)",
"categoryName": "类目名称",
"attrId": "属性ID",
"attrName": "属性名称",
"attrVal":"属性值",
"attrName": "属性值名称" }
// 关联关系(前台) sku_front_map
{
"id": "主键ID",
"spuId": "SPU ID",
"skuId": "SKU ID",
"frontCategoryId": "类目ID(叶子类目)",
"categoryName": "类目名称",
"attrId": "属性ID",
"attrName": "属性名称",
"attrVal": "属性值" }
接口设计
主要从前端商城的需求出发,重点考虑下前端在获取商品数据时的接口需求。
拉取类目
此接口主要在商城首页的商品类目展示区进行数据支撑,具体如图:
商品类目示意图
前台类目的灵活性就体现出来了,不同的前端,可能类目的设计是不一样的,这里可以做一下分类:
- PC端,视觉空间大,前台类目可以承载一定的复杂度,天猫采用的是3层结构。
- APP端,视觉空间收窄,前台类目应该简单点,层级不宜过多。
- 小程序端,交互效果相对于APP而言,进一步受制,不应该堆太多的信息元素,可以稍微做几个重点运营类目。
在参数设计上,可以根据端来进行进行不同的数据拉取。
请求参数:
{
"platform":"PC|H5|APP" }
响应参数:
// 类目接口
{
"code": 10001,
"msg": "success",
"data": [
{
"id": "类目id,int",
"name": "类目名,string",
"icon": "类目icon,string",
level2: [
{
"id": "类目id,int",
"name": "类目名,string",
"level3": [
{
"id": "类目id,int",
"name": "类目名,string",
"url": "类目指向的URL" }
]
}
]
}
]
}
根据类目拉取商品列表
当用户点击最后一级类目,网页会跳转到商品列表,此时系统需要根据类目ID拉取出商品清单。
根据类目拉取商品列表
输入参数:
{
"categoryId":18774 }
输出参数:
// 根据类目拉取商品信息
{
"code": 10001,
"msg": "success",
"data": {
"brand_list": [
{
"id": "品牌id,string",
"name": "品牌名,string",
"icon": "品牌url,string" }
],
"spu_list": [
{
"id": "商品id,long",
"name": "商品名,string",
"desc": "商品描述,string",
"price": "商品价格",
"url": "商品链接,string" }
]
}
}
根据商品spu_id拉取商品详情
当用户对某个商品有购买意向,会点击商品查看详情,这时候会进入到商品详情页,如图:
商品属性图
这时候需要系统根据商品spu_id拉取商品详情,特别是商品属性数据。
输入参数:
{
"spuId":18774 }
输出参数:
// 根据商品spuid 拉取商品详情
{
"code": 10001,
"msg": "success",
"data": {
"brand": {},// 品牌
"spu": {}, // 商品描述
"category": [ // 商品属性
{
"id": "",
"name": "",
"desc": "",
"status": "" }
]
}
}
到此为止,商品中心的核心模型和关键流程都做了设计拆解,当然,以上内容仅仅只能作为商品管理模块在系统中存在,商户中心涵盖的范围大得多,商品的信息模型确定以后,商品搜索、商品推荐 等系统服务跟上了,才能让用户达成一次较好的购物下单体验。这些内容比较独立,以后单独作为主题展开讲解。本文侧重于商品的信息模型的构建和核心流程节点中的服务接口的拆解,算是电商产品拆解的第一步吧。