前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据库设计之商品表分析2

数据库设计之商品表分析2

作者头像
多凡
发布2019-11-01 09:24:37
1.4K0
发布2019-11-01 09:24:37
举报
文章被收录于专栏:sringbootsringboot

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_44580977/article/details/100088074

在上一期,规格确定以后,就可以添加商品了,先看下数据库表

1. SPU表
代码语言:javascript
复制
CREATE TABLE `tb_spu` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'spu id',
  `title` varchar(255) NOT NULL DEFAULT '' COMMENT '标题',
  `sub_title` varchar(255) 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=208 DEFAULT CHARSET=utf8 COMMENT='spu表,该表描述的是一个抽象的商品,比如 iphone8';

与我们前面分析的基本类似,但是似乎少了一些字段,比如商品描述。

我们做了表的垂直拆分,将SPU的详情放到了另一张表:tb_spu_detail

代码语言:javascript
复制
CREATE TABLE `tb_spu_detail` (
  `spu_id` bigint(20) NOT NULL,
  `description` text COMMENT '商品描述信息',
  `specifications` varchar(3000) NOT NULL DEFAULT '' COMMENT '全部规格参数数据',
  `spec_template` varchar(1000) NOT NULL COMMENT '特有规格参数及可选值信息,json格式',
  `packing_list` varchar(1000) DEFAULT '' COMMENT '包装清单',
  `after_service` varchar(1000) DEFAULT '' COMMENT '售后服务',
  PRIMARY KEY (`spu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这张表中的数据都比较大,为了不影响主表的查询效率我们拆分出这张表。

需要注意的是这两个字段:specifications和spec_template。

1.1 SPU中的规格参数

SPU的规格参数也就是specification和spec_template这两个字段里存放的json字符串。 当你确定了一个SPU,比如小米的:红米4X

specification全局属性举例:

代码语言:javascript
复制
品牌:小米
型号:红米4X

spec_template特有属性举例:

代码语言:javascript
复制
颜色:[香槟金, 樱花粉, 磨砂黑]
内存:[2G, 3G]
机身存储:[16GB, 32GB]

来看下我们的 表如何存储这些信息:

展开specification

代码语言:javascript
复制
[{
	"group": "主体",
	"params": [{
		"k": "品牌",
		"searchable": false,
		"global": true,
		"v": "小米(MI)"
	}, {
		"k": "型号",
		"searchable": false,
		"global": true,
		"v": "小米6"
	}, {
		"k": "上市年份",
		"searchable": false,
		"global": true,
		"numerical": true,
		"unit": "年",
		"v": 2017.0
	}]
}, {
	"group": "基本信息",
	"params": [{
		"k": "机身颜色",
		"searchable": false,
		"global": false,
		"options": ["亮蓝色", "亮黑色", "陶瓷黑"]
	}, {
		"k": "机身重量(g)",
		"searchable": false,
		"global": true,
		"numerical": true,
		"unit": "g",
		"v": 168
	}, {
		"k": "机身材质工艺",
		"searchable": true,
		"global": true,
		"v": null
	}]
}, {
	"group": "存储",
	"params": [{
		"k": "内存",
		"searchable": true,
		"global": false,
		"numerical": false,
		"unit": "GB",
		"options": ["4GB", "6GB"]
	}, {
		"k": "机身存储",
		"searchable": true,
		"global": false,
		"numerical": false,
		"unit": "GB",
		"options": ["64GB", "128GB"]
	}]
}]
	...

可以看到,与规格参数表中的模板相比,最大的区别就是,这里指定了具体的值,因为商品确定了,其参数值肯定也确定了。

特有属性用举例存储。

我们发现特有属性也是有的,但是,注意看这里是不确定具体值的,因为特有属性只有在SKU中才能确定。这里只是保存了options,所有SKU属性的可选项。

在哪里会用到这个字段的值呢,商品详情页的规格参数信息中:

展开spec_template字段

代码语言:javascript
复制
{
	"机身颜色": ["亮蓝色", "亮黑色", "陶瓷黑"],
	"内存": ["4GB", "6GB"],
	"机身存储": ["64GB", "128GB"]
}

可以看出,里面只保存了规格参数中的特有属性,而且格式进行了大大的简化,只有属性的key,和待选项。

为什么要冗余保存一份?

因为很多场景下我们只需要查询特有规格属性,如果放在一起,每次查询再去分离比较麻烦。

比如,商品详情页展示可选的规格参数时:

在这里插入图片描述
在这里插入图片描述
2 SKU表
代码语言:javascript
复制
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(255) NOT NULL COMMENT '商品标题',
  `images` varchar(1000) DEFAULT '' COMMENT '商品的图片,多个图片以‘,’分割',
  `price` bigint(15) NOT NULL DEFAULT '0' COMMENT '销售价格,单位为分',
  `indexes` varchar(100) COMMENT '特有规格属性在spu属性模板中的对应下标组合',
  `own_spec` varchar(1000) 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 DEFAULT CHARSET=utf8 COMMENT='sku表,该表表示具体的商品实体,如黑色的64GB的iphone 8';

还有一张表,代表库存:

代码语言:javascript
复制
CREATE TABLE `tb_stock` (
  `sku_id` bigint(20) NOT NULL COMMENT '库存对应的商品sku id',
  `seckill_stock` int(9) DEFAULT '0' COMMENT '可秒杀库存',
  `seckill_total` int(9) DEFAULT '0' COMMENT '秒杀总数量',
  `stock` int(9) NOT NULL COMMENT '库存数量',
  PRIMARY KEY (`sku_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='库存表,代表库存,秒杀库存等信息';

问题:为什么要将库存独立一张表?

因为库存字段写频率较高,而SKU的其它字段以读为主,因此我们将两张表分离,读写不会干扰。

特别需要注意的是sku表中的indexes字段和own_spec字段。sku中应该保存特有规格参数的值,就在这两个字段中。

2.1SKU中特有规格参数
2.1.1 indexes字段

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

代码语言:javascript
复制
{
    "机身颜色": [
        "香槟金",
        "樱花粉",
        "磨砂黑"
    ],
    "内存": [
        "2GB",
        "3GB"
    ],
    "机身存储": [
        "16GB",
        "32GB"
    ]
}

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

比如:

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

你会发现,每一个属性值,对应于SPUoptions数组的一个选项,如果我们记录下角标,就是这样:

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

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

在这里插入图片描述
在这里插入图片描述

这个设计在商品详情页会特别有用:

在这里插入图片描述
在这里插入图片描述

当用户点击选中一个特有属性,你就能根据 角标快速定位到sku。

2.1.2 own_spec字段

看结构:

代码语言:javascript
复制
{"机身颜色":"香槟金","内存":"2GB","机身存储":"16GB"}

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

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

这样,在页面展示规格参数信息时,就可以根据key来获取值,用于显示。

3.总结

数据库设计要从显示物理中抽象物体的属性,将相同的属性抽离,创建简单,便于查询的表结构

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. SPU表
    • 1.1 SPU中的规格参数
      • 2.1.1 indexes字段
  • 2 SKU表
  • 2.1SKU中特有规格参数
    • 2.1.2 own_spec字段
      • 3.总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档