SPU:Standard Product Unit (标准产品单位) ,一组具有共同属性的商品集
SKU:Stock Keeping Unit(库存量单位),SPU商品集因具体特性不同而细分的每个商品
比如说小米8手机是Spu,
红色的128g存储空间,6g内存的小米8是Sku。
可以看出:
我们看下面,只要是手机的分类,都会有主体,基本信息,主芯片,存储,屏幕等参数
分类表和参数组表是一对多的关系,分类表是1,参数组表是多。比如说手机分类,对应主体,基本信息,主芯片,存储,屏幕。
可以看出一个分类(category)对应了多个(spec_group)简称为参数组,我们建立类别表和参数表。
CREATE TABLE `tb_category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '类目id',
`name` varchar(32) NOT NULL COMMENT '类目名称',
`parent_id` bigint(20) NOT NULL COMMENT '父类目id,顶级类目填0',
`is_parent` tinyint(1) NOT NULL COMMENT '是否为父节点,0为否,1为是',
`sort` int(4) NOT NULL COMMENT '排序指数,越小越靠前',
PRIMARY KEY (`id`),
KEY `key_parent_id` (`parent_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1424 DEFAULT CHARSET=utf8
CREATE TABLE `tb_spec_group` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`cid` bigint(20) NOT NULL COMMENT '商品分类id,一个分类下有多个规格组',
`name` varchar(32) NOT NULL COMMENT '规格组的名称',
PRIMARY KEY (`id`),
KEY `key_category` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8
创建参数表
Create Table
CREATE TABLE `tb_spec_param` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`cid` bigint(20) NOT NULL COMMENT '商品分类id',
`group_id` bigint(20) NOT NULL,
`name` varchar(256) NOT NULL COMMENT '参数名',
`numeric` tinyint(1) NOT NULL COMMENT '是否是数字类型参数,true或false',
`unit` varchar(256) DEFAULT '' COMMENT '数字类型参数的单位,非数字类型可以为空',
`generic` tinyint(1) NOT NULL COMMENT '是否是sku通用属性,true或false',
`searching` tinyint(1) NOT NULL COMMENT '是否用于搜索过滤,true或false',
`segments` varchar(1024) DEFAULT '' COMMENT '数值类型参数,如果需要搜索,则添加分段间隔值,如CPU频率间隔:0.5-1.0',
PRIMARY KEY (`id`),
KEY `key_group` (`group_id`),
KEY `key_category` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 COMMENT='规格参数组下的参数名'
这就需要和Spu表和Sku表联合起来看了!
上文说过Spu是一组具有共同属性的商品集,Sku是Spu商品集因具体特性不同而细分的每个商品
那么Sku,Spu表该如何创建
首先Spu肯定需要和分类表相关联,一个分类如手机对应多个Spu(手机中的小米8(Spu),华为mate30(Spu))。
一个Spu(小米8)对应多个Sku 小米8白色128g,小米8灰色64g(Sku)等。
Spu表
CREATE TABLE `tb_spu` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'spu id',
`title` varchar(128) NOT NULL DEFAULT '' COMMENT '标题',
`sub_title` varchar(256) DEFAULT '' COMMENT '子标题',
`cid1` bigint(20) NOT NULL COMMENT '1级类目id',
`cid2` bigint(20) NOT NULL COMMENT '2级类目id',
`cid3` bigint(20) NOT NULL COMMENT '3级类目id',
`brand_id` bigint(20) NOT NULL COMMENT '商品所属品牌id',
`saleable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否上架,0下架,1上架',
`valid` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,0已删除,1有效',
`create_time` datetime DEFAULT NULL COMMENT '添加时间',
`last_update_time` datetime DEFAULT NULL COMMENT '最后修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=195 DEFAULT CHARSET=utf8 COMMENT='spu表,该表描述的是一个抽象性的商品,比如 iphone8'
Sku表:
Create Table
CREATE TABLE `tb_sku` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'sku id',
`spu_id` bigint(20) NOT NULL COMMENT 'spu id',
`title` varchar(256) NOT NULL COMMENT '商品标题',
`images` varchar(1024) DEFAULT '' COMMENT '商品的图片,多个图片以‘,’分割',
`price` bigint(15) NOT NULL DEFAULT '0' COMMENT '销售价格,单位为分',
`indexes` varchar(32) DEFAULT '' COMMENT '特有规格属性在spu属性模板中的对应下标组合',
`own_spec` varchar(1024) DEFAULT '' COMMENT 'sku的特有规格参数键值对,json格式,反序列化时请使用linkedHashMap,保证有序',
`enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,0无效,1有效',
`create_time` datetime NOT NULL COMMENT '添加时间',
`last_update_time` datetime NOT NULL COMMENT '最后修改时间',
PRIMARY KEY (`id`),
KEY `key_spu_id` (`spu_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=27359021729 DEFAULT CHARSET=utf8 COMMENT='sku表,该表表示具体的商品实体,如黑色的 64g的iphone 8'
现在基本的表结构可以看作为
当我们点击商品详情的时候会携带Sku ID,通过Sku ID,拿到对应的Spu ID,拿到Spu ID后拿到Cid,
通过Cid拿到参数组表进行渲染,通过gid在参数表拿到参数头信息,怎么拿到参数信息呢?
参数信息都被保存在Spu,和Sku种,如果是某种商品集公有参数信息会保存在Spu种,
如果是可选参数会保存到Sku种。保存的数据格式均为{key1:value1,key2:value2}json数据格式。
我们现在已经拿到了SpuID,通过SpuID查询Spu表,sku表拿到参数信息进行渲染即可。
问题一:为什么要用JSON数据来保存对应关系呢?
1.如果不用json数据格式,会将Spu表和参数表和参数组表的主键放在一起,如果Spu表几亿条数据,参数表几十条,参数组表几十条,结合起来数千万亿条数据,是不现实的。而用json格式取巧的避开了大规模数据的笛卡儿积查询
问题二:库存表如何设计?
库存表应该和Sku表是一张表,而库存表的频繁的写入数据多,单独拿出来实现读写分离好。因为关系型数据库的细粒度锁,如果触发锁表操作,将严重影响读写效率。