# 1. 背景了解
在看具体的数据库实体设计之前,我们先一起了解下**电商的名词定义**
## 1.1 名词定义
参考 [《产品 SKU 是什么意思?与之相关的还有哪些?》](https://www.zhihu.com/question/19841574) 整理。
**SKU:Stock Keeping Unit**
中文翻译为库存单位。SKU 从**库存**视角,以库存进出为单位,可以是件、瓶、箱等等。
例如,iPhone 手机,按照规格( 颜色 + 内存 )可以组合出如下多个 SKU :
| SKU | 颜色 | 内存 |
| ---- | ---- | ---- |
| A | 白色 | 16G |
| B | 白色 | 64G |
| C | 黑色 | 16G |
| D | 黑色 | 64G |
可以看出,颜色(白色、黑色)与内存(16G、64G)组合排列出四种 iPhone SKU。
**SPU:Standard Product Unit**
中文翻译为标准产品单位。SPU 从**产品**视角,是产品信息聚合的**最小单位**,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。通俗点讲,属性值、特性相同的商品就可以被称为一个 SPU 。例如 iPhone 8 就是一个 SPU ,iPhone 8 Plus 也是一个 SPU ,这个与**商家**无关,与颜色、款式、套餐等**规格**无关。
**商品**:
商家出售某个 SPU ,那么这就是一个商品。商品在 SPU 之上,增加了销售价格、促销活动、运费等等信息。另外,**一个商品可以包含多个 SKU**。
**总结**
![img](https://img.kancloud.cn/61/fb/61fbccdba871f2c01de0025d3736cf9b_720x1017.png)
------
现实的场景往往比定义复杂的多,在本文中,**SKU 代表销售的单元**。主要考虑如下两方面:
- 实际我们看到的商品详情页,购买的是一个**销售组合单元**。例如,很多商家会打包 【iPhone X :银色-64G-套餐三】,其中套餐三为赠送贴膜 + 保护壳等等,当然价格上会更贵。这明显就违背了我们上述提到 SKU 库存的概念,已经变成了多个 SKU 的销售组合单元。![img](https://img.kancloud.cn/18/99/18991833539470776e26a67713e173c6_1012x1274.png)
- 一个商家会在不同平台销售商品,例如三只松鼠,其在天猫、京东等等平台都有官方旗舰店,同时也供货给其他渠道商,那么实际关系会变成如下图所示:![img](https://img.kancloud.cn/0f/86/0f86619ace0ff64527735987fc076971_1282x766.png) 通过这样的方式,三只松鼠在不同的平台,定义不同的价格,设置不同的促销信息等等个性化的运营。
------
**那么注意了**!!!
**下文开始,SKU 代表销售的单元**
**下文开始,SKU 代表销售的单元**
**下文开始,SKU 代表销售的单元**
## 1.2 界面
1. 商城端-购买页
![购买页面](https://img.kancloud.cn/68/c3/68c386cdc04a9dc2f3c187743af5ad14_1080x2160.png)
2. 运营后台-商品发布页 ![发布商品](https://img.kancloud.cn/de/bb/debbb714f491580a44cf065fd7accaf1_1605x731.png)
# 2. 数据库实体
整体实体类关系如下图:
![img](https://img.kancloud.cn/b5/6f/b56f7daf2694c2f9ea43b8e3b843b6f0_884x539.png)
全部实体可在数据库中查阅。
## 2.1 Product
Product 字段较多,我们进行简单的切块。
### 2.1.1 基础字段
```java
@Data
@TableName("tz_prod")
public class Product implements Serializable {
/**
* 商品ID
*/
@TableId
private Long prodId;
/**
* 店铺id
*/
private Long shopId;
/**
* 商品名称
*/
private String prodName;
/**
* 简要描述,卖点等
*/
private String brief;
/**
* 商品主图
*/
private String pic;
/**
* 商品图片
*/
private String imgs;
/**
* 默认是1,表示正常状态, -1表示删除, 0下架
*/
private Integer status;
/**
* 商品分类
*/
private Long categoryId;
/**
* 已经销售数量
*/
private Integer soldNum;
/**
* 录入时间
*/
private Date createTime;
/**
* 修改时间
*/
private Date updateTime;
/**
* 详细描述
*/
private String content;
/**
* 上架时间
*/
private Date putawayTime;
@Data
public static class DeliveryModeVO {
/**
* 用户自提
*/
private Boolean hasUserPickUp;
/**
* 店铺配送
*/
private Boolean hasShopDelivery;
}
}
```
- `prodId` ,商品id,数据库自增。
- `shopId` ,店铺编号,支持多商户( 店铺 )。
- `categoryId` ,商品所在分类id,每个商品都有自己所属的分类
### 2.1.2 价格库存
```java
/**
* 库存量
* 基于 sku 的库存数量累加
*/
private Integer totalStocks;
/**
* 原价
*/
private Double oriPrice;
/**
* 现价
*/
private Double price;
```
- 在我们的数据库中规定,所有的商品都是具有sku的,就算是只有一种规格的商品,所以`product`里面的库存数量为所有sku库存数量的总和
- `price` ,商品价格为元,这里使用`Double`而没有使用`BigDecimal `,而数据库中使用`decimal` 进行存储,所以在数据库中是可以进行直接进行运算的,而在java当中需要使用`com.yami.shop.common.util.Arith`进行运算 。
### 2.1.3 运费信息
```java
/**
* 配送方式json
*/
private String deliveryMode;
/**
* 运费模板id
*/
private Long deliveryTemplateId;
@Data
public static class DeliveryModeVO {
/**
* 用户自提
*/
private Boolean hasUserPickUp;
/**
* 店铺配送
*/
private Boolean hasShopDelivery;
}
```
- 根据` deliveryMode `标记所含有的配送方式进行配送。
- `deliveryTemplateId` 运费模板id,根据不同的运费模板设计不同的配送费
![img](https://img.kancloud.cn/6f/33/6f33f568c70b7a662cb5b66a88d263ae_1615x426.png)
运费模板的操作见 :运费模板的设计相关文章。
## 2.2 Sku
商品 SKU 。
![img](https://img.kancloud.cn/a3/e0/a3e0540c1099b9ed7ebeb9a5df523e09_1624x540.png)
```java
@Data
@TableName("tz_sku")
public class Sku implements Serializable {
/**
* 单品ID
*/
@TableId
private Long skuId;
/**
* 商品ID
*/
private Long prodId;
/**
* 销售属性组合字符串,格式是p1:v1;p2:v2
*/
private String properties;
/**
* 原价
*/
private Double oriPrice;
/**
* 价格
*/
private Double price;
/**
* 库存
*/
private Integer stocks;
/**
* 实际库存
*/
private Integer actualStocks;
/**
* 修改时间
*/
private Date updateTime;
/**
* 记录时间
*/
private Date recTime;
/**
* 商家编码
*/
private String partyCode;
/**
* 商品条形码
*/
private String modelId;
/**
* sku图片
*/
private String pic;
/**
* sku名称
*/
private String skuName;
/**
* 商品名称
*/
private String prodName;
/**
* 重量
*/
private Double weight;
/**
* 体积
*/
private Double volume;
/**
* 状态:0禁用 1 启用
*/
private Integer status;
/**
* 0 正常 1 已被删除
*/
private Integer isDelete;
}
```
- `skuId` ,SKU 编号,自增,唯一,参见分销场景。
- `prodId` ,商品编号,N:1 指向对应的 Product 。
- `status`,SKU 状态。编辑商品时,当禁用该sku时,前端将会将该sku置灰
- `stocks` ,库存数量。
- `properties`,商品规格,字符串拼接格式。
绝大多数情况下,数据库里的该字段,不存在检索的需求,更多的时候,是查询整体记录,在内存中解析使用。
少部分情况,灵活的检索,使用 Elasticsearch 进行解决。
因为我们的规格是直接保存字符串的,所以可以选择,或直接输入
![img](https://img.kancloud.cn/03/c4/03c4d9efabb9a0d3a0c26b03708ea4de_301x288.png)![img](https://img.kancloud.cn/c0/26/c02648a1ee81fdecd66eda2e3e130a1a_413x154.png)
## 2.3 ProdProp
商品 SKU 规格属性,在数据库中保存的常用数据。不常用的数据可以直接手动输入即可。
![img](https://img.kancloud.cn/51/30/51304de887559e2581b4149c3d842d16_1651x411.png)
```java
public class ProdProp implements Serializable {
/**
* 属性id
*/
@TableId
private Long propId;
/**
* 属性名称
*/
private String propName;
private Long shopId;
}
```
- `propId` ,属性编号。
- `propName` ,属性名称。
## 2.4 ProdPropValue
商品 SKU 规格属性,在数据库中保存的常用数据。
```java
public class ProdProp implements Serializable {
/**
* 属性值ID
*/
@TableId
private Long valueId;
/**
* 属性值名称
*/
private String propValue;
/**
* 属性ID
*/
private Long propId;
}
```
- `valueId` ,属性值ID。
- `propValue` ,属性值名称。
- 开发环境准备
- 基本开发手册
- 项目目录结构
- 权限管理
- 通用分页表格
- Swagger文档
- undertow容器
- 对xss攻击的防御
- 分布式锁
- 统一的系统日志
- 统一验证
- 统一异常处理
- 文件上传下载
- 一对多、多对多分页
- 认证与授权
- 从授权开始看源码
- 自己写个授权的方法-开源版
- 商城表设计
- 商品信息
- 商品分组
- 购物车
- 订单
- 地区管理
- 运费模板
- 接口设计
- 必读
- 购物车的设计
- 订单设计-确认订单
- 订单设计-提交订单
- 订单设计-支付
- 生产环境
- nginx安装与跨域配置
- 安装mysql
- 安装redis
- 传统方式部署项目
- docker
- 使用docker部署商城
- centos jdk安装
- docker centos 安装
- Docker Compose 安装与卸载
- docker 镜像的基本操作
- docker 容器的基本操作
- 通过yum安装maven
- 常见问题