数据建模指的是对现实世界各类数据的抽象组织,确定数据库需管辖的范围、数据的组织形式等直至转化成现实的数据库。 将经过系统分析后抽象出来的概念模型转化为物理模型后,在visio或erwin等工具建立数据库实体以及各实体之间关系的过程(实体一般是表)。
在软件工程中,数据建模是运用正式的数据建模技术,建立信息系统的数据模型的过程。
数据模型:是现实世界数据特征的抽象,用于描述一组数据的概念和定义。是数据库中数据的组织和存储方式,是数据库系统的核心和基础。
简单来说,在软件系统的数据库设计中,数据建模就是使用表和表之间的关系来反映现实业务抽象出来的实体和实体之间的关系。
1.2 为什么要做数据建模?从技术角度来说,一个大型的软件系统会产生海量的、结构各异的数据,数据库建的好不好,直接关系到系统的开发、后期维护、扩展以及性能优化的效率和成本。
1.3 如何进行数据建模?数据模型按不同的应用层次分成三种类型,分别是:概念数据模型、逻辑数据模型、物理数据模型。对应的,数据建模可以分为三大阶段:概念建模阶段、逻辑建模阶段、物理建模阶段。其中概念建模和逻辑建模阶段与数据库厂商(MySQL,SQL Server,Oracle等)毫无关系。物理建模阶段和数据库厂商存在很大的联系,因为不同厂商对同一功能的支持方式不同,如高可用性,读写分离,甚至是索引,分区等。
数据建模三大阶段:
1)概念建模阶段
了解业务,理解需求,然后建立概念模型,确定实体以及实体关系。在概念建模阶段,我们只需要关注实体即可,不用关注任何实现细节。
具体建模时产物参考京东商城建模的 2.1分析业务需求、2.2 定义实体、2.3定义实体间的关系、2.4 E-R图,该阶段生成的是基础E-R图,可以不包含属性。
2)逻辑建模阶段
细化实体成具体的表,同时丰富表结构,确定实体属性,依据三大范式标准化数据。这个阶段的产物是,可以在数据库中生成的具体表及其他数据库对象(包括,主键,外键,属性列,索引,约束甚至是视图以及存储过程)。
但一般在实际项目中,除了主外键和属性列之外,其他的数据库对象在物理建模阶段建立更为合适,因为其他数据库对象更贴近于开发,需要结合开发一起进行。如约束,我们可以在前端页面上做JavaScript约束,也可以在业务逻辑层做,也可以在数据库中做,在哪里做,要结合实际需求,性能以及安全性而定。
具体建模时产物参考京东商城建模的2.5 表结构,需要根据基本E-R图,确定实体的全部属性,确定因为业务需要增加的表。
3)物理建模阶段
将在逻辑建模阶段创建的各种数据库对象生成为相应的SQL代码,运行来创建相应具体数据库对象。这个阶段我们不仅仅创建数据库对象,也可以针对业务需求,做数据拆分、读写分离等。刚才在逻辑建模提到的数据库中索引,约束、视图和存储过程等数据库对象,就可以在这个阶段产生。
另外,关于关系型数据库遵守的范式规则,3NF是经典也确实很好,但是范式越高就意味着表的划分更细,一个数据库中需要的表也就越多,我们不得不把原本相关联的数据分摊到多个表中。这样可能会增加程序逻辑,甚至可能需要同时把两张或者多张数据非常庞大的表进行表连接,表连接操作会很明显地降低系统运行性能。所以,在整个数据建模过程中,在保证数据结构清晰的前提下,尽量提高性能才是我们关注的要点,可以允许数据适当冗余。当然,在最开始的概念建模和逻辑建模阶段,还是应该尽量遵守3NF的。没有最好的设计,只有最合适的设计。
以上就是对数据建模的理论介绍,本次跟大家分享和探讨的是京东商城的数据建模,分享内容的是数据建模前两个阶段的产物。
2.京东商城的数据建模
京东商城是一个电商网站,最基础的需求是:用户在网站中购买到高性价比的商品。从这句话我们可以得出三个实体,用户、网站、商品。所以在概念建模阶段,我们产出的实体就是用户和商品。(此处我们不需要考虑网站这个实体)
接下来我们从用户的角度,梳理下京东商城的业务需求。由于商家或供应商的信息很多拿不到,所以这里就不讲商家了。
2.1分析业务需求1)用户可以使用手机号注册账户,之后可以使用这个手机号登录系统进行交易。
2)用户可以浏览商品。
3)用户可以添加商品到购物车。
4)用户可以提交并查看订单。
5)用户可以支付订单。
6)用户可以关注商品。
7)用户可以评价已购买商品。
2.2 定义实体用户
商品
购物车
订单
2.3 定义实体间的关系用户:
- 一个用户拥有一个账户,是一对一
- 一个账户有多个登录设备,是一对多
- 一个账户有多个支付工具,是一对多
- 一个用户有多个地址信息,是一对多
- 一个用户可以购买多张plus会员卡,一个plus会员卡可以被多个用户购买,是多对多
- 一个用户可以浏览多个商品,一个商品可以被多个用户浏览,是多对多
商品:
-
一个分类有多个品牌,一个品牌属于多个分类,是多对多
-
一个分类有多个参数组,是一对多
-
一个参数组下有多个规格参数,是一对多
-
一个品牌下有多个SPU,是一对多
-
一个SPU下有多个SKU,是一对多
购物车:
- 一个商品可以被添加到多个购物车中,一个购物车可以添加多个商品,是多对多
订单:
- 一个购物车可以生成多个订单,是一对多
- 一个订单包含一个支付流水,是一对一
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | |
| 用户名 | username | varchar(32) | - | - | - | 否 | 注册后系统生成,无法修改 |
| 头像地址 | image_url | varchar(256) | - | - | - | 否 | |
| 昵称 | nick_name | varchar(32) | - | - | - | 否 | |
| 性别 | gender | tinyint(1) | - | - | 2 | 否 | 0-男,1-女,2-默认 |
| 出生日期 | birthday | varchar(32) | - | - | ‘’ | 是 | |
| 京享值 | score | bigint(20) | - | - | - | 否 | |
| 是否是plus会员 | is_plus | tinyint(1) | - | - | 0 | 否 | 0-否,1-是 |
| 累计已省金额 | save_amount | decimal(10,2) | - | - | 0 | 是 | 与是否购买过plus会员相关 |
| 已返京豆 | refund_bean | bigint(20) | - | - | 0 | 是 | 与是否购买过plus会员相关 |
| 是否开启plus自动续费 | plus_auto_renew | tinyint(1) | - | - | 0 | 否 | 0-否,1-是 |
| plus自动续费扣款工具 | pay_means_id | bigint(20) | - | - | - | 是 | 当未开启自动续费,则为空 |
| 创建时间 | create_time | timestamp | - | - | 当前时间戳 | 是 | 创建时间戳 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2tV4oby2-1602499867140)(./img/我的信息.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CZZWyl7Y-1602499867142)(./img/个人信息.png)]
账户安全表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | |
| 登录密码 | loginpwd | varchar(32) | - | - | - | 否 | |
| 是否开启刷脸登录 | face_login | tinyint(1) | - | - | 0 | 否 | 0-否,1-是 |
| 人脸信息地址 | face_url | varchar(256) | - | - | ‘’ | 是 | 存储人脸信息,当未开启刷脸登录则该字段为空 |
| 关联QQ号 | qq_num | varchar(32) | - | - | ‘’ | 是 | |
| 关联微信号 | weichat_num | varchar(32) | - | - | ‘’ | 是 | |
| 手机号 | phone_number | varchar(32) | - | - | - | 否 | 登录使用的手机号 |
| 邮箱 | varchar(32) | - | - | ‘’ | 否 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VZ4SS9wT-1602499867147)(./img/账户安全.png)]
实名信息表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 账户安全id | account_id | bigint(20) | - | 是 | - | 否 | |
| 真实姓名 | realname | varchar(32) | - | - | - | 否 | 绑定银行卡时需要实名认证 |
| 性别 | sex | tinyint(1) | - | - | - | 否 | 0-男,1-女 |
| 国家/地区 | country | varchar(32) | - | - | - | 否 | |
| 证件类型 | id_type | varchar(32) | - | - | - | 否 | |
| 证件号码 | id_number | varchar(32) | - | - | - | 否 | |
| 证件有效期 | expire_date | varchar(32) | - | - | ‘’ | 是 | |
| 职业类型 | career_type | tinyint(1) | - | - | ‘’ | 是 | 在职,学生,退(离)休人员,无业人员,不便分类的其他劳动者 |
| 居住情况 | live_type | tinyint(1) | - | - | ‘’ | 是 | 自有,借住,租房,其他 |
| 所在地区 | location_id | bigint(20) | - | - | ‘’ | 是 | |
| 详细地址 | where | varchar(256) | - | - | ‘’ | 是 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h9vJSlT2-1602499867151)(./img/实名信息.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lVsNGsvn-1602499867153)(./img/地址.png)]
设备管理表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 账户安全id | account_id | bigint(20) | - | 是 | - | 否 | |
| 设备名称 | name | varchar(32) | - | - | - | 否 | |
| 设备型号 | device_type | varchar(32) | - | - | ‘’ | 否 | |
| 添加时间 | create_time | timestamp | - | - | 当前时间戳 | 是 | 创建时间戳 |
| 最后更新时间 | update_time | timestamp | - | - | 当前时间戳 | 是 | 更新表时间戳,可以用来显示上次登录时间 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mgzJ2GCr-1602499867156)(./img/设备管理.png)]
支付设置表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | |
| 支付密码 | paypwd | varchar(32) | - | - | - | 否 | |
| 是否开启小额免密 | no_pwd_pay | tinyint(1) | - | - | 0 | 否 | 0-否,1-是 |
| 其他支付方式 | pay_types | tinyint(1) | - | - | 0 | 否 | 0-不支持,1-支持指纹支付,2-支持面容id支付,3-都支持 |
| 默认支付工具 | pay_means_id | bigint(20) | - | - | - | 是 | 关联支付工具表 |
| 支付需要验密 | verify_pwd | tinyint(1) | - | - | 1 | 否 | 0-否,1-是 |
| 刷脸支付 | face_pay | varchar(32) | - | - | 0 | 否 | 0-否,1-是 |
pay_types:需要本地根据设备判断,显示支付方式入口,默认是都不支持。
银行卡属于支付工具,所以单独提出来一个表。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XaCR5TAG-1602499867158)(./img/支付设置.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2qXwhpl6-1602499867164)(./img/默认工具.png)]
支付工具表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 支付设置_id | payset_id | bigint(20) | - | 是 | - | 否 | |
| 用户id | uid | bigint(20) | - | - | - | 否 | |
| 工具类型 | types | tinyint(1) | - | - | - | 否 | 0-小金库,1-信用卡,2-储蓄卡,3-白条,4-微信 |
| 所属银行 | bank | varchar(32) | - | - | - | 是 | |
| 银行卡号 | card_number | varchar(32) | - | - | - | 是 | |
| 银行卡预留手机号 | card_phone | varchar(32) | - | - | - | 是 | |
| 添加时间 | create_time | timestamp | - | - | 当前时间戳 | 否 | 前端用来排序显示 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M7yRMvpD-1602499867165)(./img/银行卡.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9G2X9Lcz-1602499867166)(./img/银行卡2.png)]
1.工具类型:存储了微信类型,在支付流水表会用到。此处不绑定微信支付账户,但需要保证有微信支付工具,以便与第三方支付订单编号关联。
地址信息表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | |
| 收货人 | name | varchar(32) | - | - | - | 否 | |
| 手机号码 | phone | varchar(32) | - | - | - | 否 | |
| 国家/地区id | nation_id | bigint(20) | - | 是 | - | 否 | 与手机号区号相关 |
| 省/行政区id | province_id | bigint(20) | - | 是 | - | 否 | |
| 市id | city_id | bigint(20) | - | 是 | - | 否 | |
| 区/县id | country_id | bigint(20) | - | 是 | - | 否 | |
| 乡/镇/街道id | town_id | bigint(20) | - | 是 | - | 否 | 地址信息必须具体到乡/镇/街道 |
| 详细地址 | where | varchar(256) | - | - | - | 否 | |
| 是否是默认地址 | address_default | tinyint(1) | - | - | - | 否 | 0-否,1-是 |
| 标签名称 | tag_name | varchar(32) | - | - | - | 是 | 为空则代表没有选择标签, |
1.手机号区号与所选国家/地区是相关的,所以将手机区号存在了国家/地区表中,根据国家/地区表中主键id,可以查询到对应的区号。
2.标签名称:当为空则没选择标签,选择后则存储该标签的名称。
3.国家/地区表、省/行政表、市信息表、区/县表、乡/镇/街道表 与 地址信息表,均是一对多的关系,所以5个地区表的主键都设置了外键。另外,京东在请求地区信息时,如果已经选择好中国,点击修改地址会同时请求4个接口,一次性查出来中国全部的省,市,区,乡镇的数据,这是设置外键的另一个原因。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pFDzQMIF-1602499867169)(./img/收货地址1.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NadOxIHn-1602499867170)(./img/收货地址2.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKHTDaaM-1602499867173)(./img/手机号区号.png)]
国家/地区表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 国家/地区名称 | nation_name | varchar(32) | - | - | - | 否 | |
| 区号 | area_code | varchar(32) | - | - | - | 否 | 部分地区区号有0/00开头,所以设置了varchar类型 |
由于选择国家/地区,手机区号是联动的,会跟随地区一起变更,所以将手机区号加到该国家/地区表中。少新建一个区号表,减少数据冗余。
省/行政区表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 所属国家/地区id | nation_id | bigint(20) | - | 是 | - | 否 | |
| 省份名称 | province_name | varchar(32) | - | - | - | 否 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 所属省/行政区id | province_id | bigint(20) | - | 是 | - | 否 | |
| 市名称 | city_name | varchar(32) | - | - | - | 否 |
中国有4个直辖市:北京、上海、天津、重庆,直辖市的行政地位与省、自治区、特别行政区相同。通过查看实际功能可以发现,北京市下面只有2级地区(区、乡镇/街道),所以北京市在数据库存储时,在省/行政区信息表中,存储北京市,在市信息表中,也存储北京市。
用公司所在的地址,从数据库中查询到的完整地区信息应该是:中国大陆(国家)–北京(直辖市)–北京(市)–大兴区(区)–亦庄经济开发区(街道)
区/县表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 所属市id | city_id | bigint(20) | - | 是 | - | 否 | |
| 区/县名称 | country_name | varchar(32) | - | - | - | 否 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 所属区/县id | country_id | bigint(20) | - | 是 | - | 是 | |
| 乡/镇/街道名称 | town_name | varchar(32) | - | - | - | 否 | |
| 经度 | latitude | varchar(32) | - | - | - | 是 | |
| 纬度 | longitude | varchar(32) | - | - | - | 是 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 会员卡类型 | plus_type | tinyint(1) | - | - | - | 否 | 0-年卡会员,1-试用会员,2-联名卡 |
| 会员卡名称 | card_name | varchar(256) | - | - | - | 否 | |
| 会员卡价格 | card_price | decimal(10,2) | - | - | - | 否 | |
| 会员卡有效时长 | period | varchar(32) | - | - | - | 否 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-apOYsVC6-1602499867174)(./img/plus会员.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HiKz9IH-1602499867175)(./img/会员购买记录.png)]
plus会员购买记录表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | |
| 会员卡id | plus_card_id | bigint(20) | - | 是 | - | 否 | |
| 会员卡交易时间 | trans_time | timestamp | - | - | - | 否 | |
| 会员卡到期时间 | expire_time | timestamp | - | - | - | 否 | |
| 订单号 | order_num | varchar(32) | - | - | - | 否 | 与自增id不一样,一般是有含义的一段字符组合 |
| 订单状态 | order_status | varchar(32) | - | - | - | 否 | |
| 实付金额 | pay_amount | decimal(10,2) | - | - | - | 否 | |
| 是否自动扣款 | auto_pay | tinyint(1) | - | - | - | 否 | 0-否,1-是 |
| 支付端 | pay_client | tinyint(1) | - | - | - | 否 | 0-PC,1-APP |
| 支付方式 | pay_means | tinyint(1) | - | - | - | 否 | 0-微信,1-支付宝,2-小金库,3-白条,4-银行卡 |
| 退款时间 | refund_time | timestamp | - | - | - | 是 | 退款成功的时间 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 类别名称 | name | varchar(32) | - | - | - | 否 | |
| 父类别id | parent_id | bigint(20) | - | - | - | 否 | 父类别id,顶级类别为0 |
| 是否为父节点 | is_parent | tinyint(1) | - | - | - | 否 | 0-否,1-是 |
| 排序指数 | sort | tinyint(2) | - | - | - | 否 | 排序指数,越小越靠前 |
父类别id:目前京东实现的是3级分类,这里设置了父类别id,方便后期扩展。这个字段可以设置一个索引,方便查询。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BqV1t8F7-1602499867177)(./img/商品分类.png)]
品牌表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 品牌名称 | name | varchar(64) | - | - | - | 否 | 官方品牌名称 |
| 品牌图片 | logo_url | varchar(256) | - | - | ‘’ | 是 | 存储品牌logo的url |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6gf5whVm-1602499867178)(./img/品牌.png)]
分类品牌表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 类别id | category_id | bigint(20) | 是 | - | - | 否 | |
| 品牌id | brand_id | bigint(20) | 是 | - | - | 否 |
商品分类表和品牌表:多对多关系,涉及一个中间表,这两个字段做联合主键。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-blOeLoc2-1602499867180)(./img/参数组.png)]
查看商品的规格与包装,可以看出,不同类别的商品,他们的参数组是不一样的,比如手机和空调。
但同类的商品,他们的参数规格名称都是一样的,只是值不同,比如手机类别下,华为手机和苹果手机的参数规格名称都相同。
也就是说,商品的规格参数与分类是绑定的。每一个类别都有统一的规格参数模板,但是不同商品其参数值可能不同。
参数组表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 商品类别id | category_id | bigint(20) | - | 是 | - | 否 | 一个类别下有多个参数规格组 |
| 参数组名 | name | varchar(32) | - | - | - | 否 | 参数规格组名称 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 参数组id | group_id | bigint(20) | - | 是 | - | 否 | 参数所属参数组 |
| 参数名 | name | varchar(128) | - | - | - | 否 | |
| 是否是通用属性 | generic | tinyint(1) | - | - | - | 否 | 是否是sku通用属性 |
| 是否用来过滤 | searching | tinyint(1) | - | - | - | 否 | 是否用于搜索过滤 |
| 参数值区间 | segments | varchar(1024) | - | - | ‘’ | 是 | 参数值按区间划分 |
1.generic:是否是通用属性。true表示是通用属性,false表示是特有属性。用于后面对同一商品spu,使用特有属性筛选出具体的sku。在后面的商品表中会体现出这个参数的作用。
2.以搜素手机为例,过滤条件中的屏幕尺寸、运行内存、电池容量、屏占比等,在规格参数汇总页都可以找到,所以规格参数中的一部分数据会用来在搜索时,作为过滤条件。
searching:标记是否用作过滤。0表示用于过滤搜索,1表示不用于过滤。
segments:某些参数,在搜索时需要按区间划分,这个字段可以标注好该商品的这一个参数值所在区间,比如电池容量,1200mAh以下,1200mAh-2999mAh,3000mAh-3499mAh,3500mAh-3749mAh…。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qz4So4JL-1602499867182)(./img/参数值所属区间.png)]
先了解下SPU和SKU。
SPU = Standard Product Unit (标准产品单位)
SPU一组具有共同属性的商品集,该集合描述了一个产品的特性。如手机->Apple手机->iphone 11,iphone11就是SPU,与颜色、款式、套餐都无关。
SKU=stock keeping unit(库存量单位)
SKU即库存进出计量的单位, 是物理上不可分割的最小存货单元。SPU商品集因具体特性不同而细分的每个商品。如绿色 128G iphone11。
SPU是一个抽象的商品集概念,方便后台管理。而SKU是具体要销售的商品,每一个SKU的价格、库存可能会不一样。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p1LDQviO-1602499867183)(./img/spu.png)]
SPU表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 店铺id | store_id | bigint(20) | - | 是 | - | 否 | 商品所属店铺id |
| 是否京东自营 | belong_jd | tinyint(1) | - | - | - | 否 | 0-否,1-是 |
| 商品名称 | name | varchar(256) | - | - | - | 否 | |
| 副标题 | sub_title | varchar(512) | - | - | ‘’ | 是 | 一般是促销信息 |
| 类别id | cid | bigint(20) | - | 是 | - | 否 | 所属3级类别 |
| 品牌id | brand_id | bigint(20) | - | 是 | - | 否 | 商品所属品牌 |
| 是否有效 | saleable | tinyint(1) | - | - | 1 | 否 | 0-下架,1-上架 |
| 商品描述 | description | text | - | - | - | 否 | |
| 包装清单 | packing_list | varchar(2048) | - | - | ‘’ | 否 | |
| 售后服务 | after_service | varchar(2048) | - | - | ‘’ | 否 | |
| 价格说明 | price_depiction | varchar(2048) | - | - | ‘’ | 是 | |
| 能效说明 | statement | varchar(2048) | - | - | ‘’ | 是 | 一些电器会有该字段内容 |
1.cid:商品类别id,在商品类别表中,由于目前京东商城实现的是3级分类,在这里可以设置商品所属的第3级分类类别id为外键,与商品分类表关联。
2.saleable:设置商品是否有效。当该SPU下所有的SPU都没有库存,代表该SPU下架,就无效。
SPU参数表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| spu id | spu_id | bigint(20) | 是 | - | - | 否 | |
| 参数id | param_id | bigint(20) | 是 | - | - | 否 | |
| 参数值 | value | varchar(1024) | - | - | - | 否 | 特有属性存的是一个数组 |
前面我们讲过,规格参数表中,有个generic字段,判断该参数是否是通用规格参数,由此可以将规格参数分成通用规格参数和特有规格参数。
以手机为例,品牌、操作系统等肯定是通用规格属性,它的值只有1个,内存、颜色等肯定是特有规格属性,它的值有多个。
因为在商品详情页,选择了spu的一个特有属性(如颜色),则需要把对应的所有规格参数值都显示出来(该颜色对应的版本),为了渲染方便所以这里把参数值聚合起来存的是一个数组类型。特有属性的参数值在sku表中会使用到。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hOkQMDJt-1602499867187)(./img/选择spu.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9iOg0MDJ-1602499867188)(./img/商品.png)]
SKU表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| spu id | spu_id | bigint(20) | - | 是 | - | 否 | 所属spu |
| 商品标题 | title | varchar(256) | - | - | - | 否 | |
| 库存 | stock | int(10) | - | - | 9999 | 是 | |
| 价格 | origin_price | decimal(10,2) | - | - | 0 | 否 | 商品价格,单位为分 |
| 特有规格参数下标组合 | indexes | varchar(32) | - | - | ‘’ | 是 | 特有规格属性在spu属性模板中的对应下标组合 |
1.indexes:特有规格属性在SPU参数表中的对应下标组合。
以手机为例,spu id为128的iPhone11 两条特有参数数据:
| spu id | param_id | value |
|---|---|---|
| 128 | 4 | [“白色”, “黑色”, “红色”] |
| 128 | 13 | [“64GB”, “128GB”] |
根据以上两条数据,参数值排列组合,可以得出:
- iPhone 11,白色,64GB:0_0
- iPhone 11,黑色,64GB:1_0
- iPhone 11,红色,128GB:2_1
- …
这些特有属性进行排列组合,会有6种,indexes保存的就是这些参数值对应下标组合,从而可以确认具体的sku的特有属性值。
商品库存表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增 |
| 仓库id | warehouse_id | bigint(20) | - | 是 | - | 否 | |
| sku id | sku_id | bigint(20) | - | 是 | - | 否 | |
| 入库批次 | batch | varchar(128) | - | - | 1 | 否 | 一个商品,可能是分不同批次存入仓库的 |
| 商品状态 | sku_type | tinyint(1) | - | - | - | 否 | 枚举值:1-良品;2-残品;3-样品 |
| 库存数量 | stock_num | bigint(20) | - | - | - | 否 | |
| 入库时间 | create_time | timestamp | - | - | 当前时间戳 | 否 | 可以根据入库时间,确认商品是否是临期产品 |
对于京东自营的商品,可以通过地区,该地区的库存,确认商品是否可以购买。
目前京东商城是有7大物流中心,包含335个大型仓库,每个仓库都是有辐射的区域。比如说 华北(北京)物流中心覆盖:北京市、天津市、河北省、山东省、山西省、内蒙古自治区,而华北物流中心的1号和2号仓库存储北京市商品。可以通过当前选择地址,属于哪个仓库覆盖范围,来确定库存。
因为仓库和商品是多对多的关系,所以可以建一个多对多关系表。
SKU图片表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| sku id | sku_id | bigint(20) | - | 是 | - | 否 | |
| 图片/视频地址 | img_url | varchar(1024) | - | - | - | 否 | |
| 排序指数 | sort | tinyint(2) | - | - | - | 否 | 排序指数,越小越靠前 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FlbR09QP-1602499867191)(./img/详情1.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MyZVsX1g-1602499867192)(./img/详情2.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZhqHAK1a-1602499867193)(./img/详情3.png)]
2.5.3用户商品关系表 商品评价表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| sku id | sku_id | bigint(20) | - | 是 | - | 否 | |
| 订单id | order_id | bigint(20) | - | 是 | - | 否 | |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | |
| 商品评价得分 | score | tinyint(1) | - | - | 5 | 是 | 当该评论是追加评价时,无需给出评分 |
| 是否是追加评价 | is_add_comment | tinyint(1) | - | - | 0 | 是 | 0-否,1-是 |
| 是否匿名 | is_anonymous | tinyint(1) | - | - | 1 | 是 | 0-否,1-是,当是追加评价时,则取上次评价的值 |
| 是否有图 | has_picture | tinyint(1) | - | - | 0 | 是 | 0-否,1-是 |
| 评价文本 | comment_text | varchar(2048) | - | - | ‘’ | 否 | 评价文本上限500字 |
| 评价标签id | tag_id | bigint(20) | - | - | - | 是 | 当该商品没有评价分类时,则为空 |
| 点赞数 | agree | bigint(20) | - | - | 0 | 是 | |
| 添加时间 | create_time | timestamp | - | - | 当前时间戳 | 否 | 创建时间戳 |
商品评价表,其实是用户评价商品(sku)产生的一张多对多的表,也可以使用sku id和用户id 做联合索引查询。
1.追加评价:追加评价时,无需插入商品评价得分。由于系统默认评价是 5星好评,匿名,故评分默认值为5。是匿名。
2.是否有图(has_picture):在用户查看商品时,有一个查看带图的评价,可以使用该字段筛选。
3.订单id:一个用户可以多次购买同一商品,进行评价,所以需要存储订单id来确保数据唯一性。
商品评价标签表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| sku id | sku_id | bigint(20) | - | 是 | - | 否 | |
| 标签名称 | tag_name | varchar(128) | - | - | - | 否 | |
| 评价数 | count_num | bigint(20) | - | - | - | 否 | |
| 匹配字段 | tag_content | varchar(1024) | - | - | - | 否 | 当新的评论中存在该字段,则属于该标签 |
| 是否用来过滤 | filtered | tinyint(1) | - | - | 0 | 是 | 0-否,1-是 |
商品评价标签表是在产生了评价后,才会产生商品评价标签表。所以商品评价表中的评价标签id(tag_id)最开始没有标签时,则为空。
评价图片表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 评价id | comment_id | bigint(20) | - | 是 | - | 否 | |
| 图片/视频地址 | img_url | varchar(1024) | - | - | - | 否 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 评价id | comment_id | bigint(20) | - | 是 | - | 否 | |
| 用户id | uid | bigint(20) | - | 是 | - | 否 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 评价id | comment_id | bigint(20) | - | 是 | - | 否 | |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | 用户id/商家客服id |
| 是否是商家 | is_stuff | tinyint(1) | - | - | 0 | 否 | 0-否,1-是 |
| 回复文本 | reply_text | varchar(1024) | - | - | - | 否 | 评论 |
| 回复时间 | create_time | timestamp | - | - | 当前时间戳 | 否 | 创建时间戳 |
1.京东支持回复评价的回复,即楼中楼,但回复成功后,显示方式与评价的回复一样,并不会显示回复的是谁发布的回复,只是按照回复时间倒序排序,故所有回复均存在一个表中。
2.如果是商家回复,需要在前端做显示的区分,所以设置一个属性,判断是否是商家回复。
回复点赞表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 回复id | reply_id | bigint(20) | - | 是 | - | 否 | |
| 用户id | uid | bigint(20) | - | 是 | - | 否 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pEi88iJR-1602499867205)(./img/评价1.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ACM5MDpU-1602499867207)(./img/评价2.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SXbRwfey-1602499867209)(./img/回复.png)]
商品关注表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | |
| 商品id | sku_id | bigint(20) | - | 是 | - | 否 | |
| 关注时商品价格 | present_price | decimal(10,2) | - | - | - | 否 | |
| 关注时间 | create_time | timestamp | - | - | 当前时间戳 | 是 | 创建时间戳 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 用户id | uid | bigint(20) | - | - | - | 否 | |
| 商品id | sku_id | bigint(20) | - | - | - | 否 | |
| 首次浏览时间 | create_time | timestamp | - | - | 当前时间戳 | 是 | 创建时间戳 |
| 最近一次浏览时间 | update_time | timestamp | - | - | 当前时间戳 | 是 | 记录更新时间 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hjWQwLuh-1602499867212)(./img/商品关注.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1XUORCC-1602499867213)(./img/浏览记录.png)]
2.5.4购物车 购物车表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 用户id | uid | bigint(20) | - | 是 | - | 否 |
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 购物车id | cart_id | bigint(20) | - | 是 | - | 否 | |
| 商品 id | sku_id | bigint(20) | - | 是 | - | 否 | |
| 商品数量 | number | int(8) | - | - | - | 否 | |
| 添加时价格 | add_price | decimal(10,2) | - | - | - | 否 | |
| 当前价格 | present_price | decimal(10,2) | - | - | - | 否 | |
| 添加时间 | create_time | timestamp | - | - | 当前时间戳 | 否 | 添加商品时间戳 |
1.购物车中的商品分类,可以使用sku_id查询到。
2.是否是京东自营,则根据sku所属的spu的spu_id查得到。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wu58BgMZ-1602499867215)(./img/购物车.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YbxqaaN1-1602499867217)(./img/购物车分类.png)]
2.5.5订单 订单表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 用户id | uid | bigint(20) | - | 是 | - | 否 | |
| 订单号 | orderno | varchar(256) | - | - | - | 否 | 有一定意义的编号,比如时间戳+用户id+自增数 |
| 订单状态 | status | tinyint(1) | - | - | - | 否 | 0-待付款,1-待收货,2-已完成,3-已取消 |
| 下单时间 | sub_time | timestamp | - | - | 当前时间戳 | 否 | 生成订单的时间 |
| 支付方式 | pay_method | tinyint(1) | - | - | - | 否 | 0-在线支付,1-货到付款 |
| 店铺id | store_id | bigint(20) | - | - | - | 否 | 一般一个店铺会生成一个订单 |
| 商品信息 | sku_details | varchar(2048) | - | - | - | 否 | |
| 商品数量 | number | bigint(20) | - | - | - | 否 | |
| 订单留言 | message | varchar(1024) | - | - | - | 否 | |
| 发票id | bill_id | bigint(20) | - | - | - | 否 | 关联发票表 |
| 收货人姓名 | rec_name | varchar(256) | - | - | - | 否 | |
| 收货人手机号 | rec_phone | varchar(128) | - | - | - | 否 | |
| 收货人地址 | rec_address | varchar(2048) | - | - | - | 否 | |
| 货运单号 | freight_no | varchar(256) | - | - | - | 是 | |
| 配送方式 | delivery_method | tinyint(1) | - | - | - | 是 | 普通快递,京东物流,上门自提 |
| 提货地址 | delivery_address | varchar(2048) | - | - | - | 否 | |
| 运费 | freight_fare | decimal(10,2) | - | - | - | 否 | |
| 期望配送日期 | freight_date | varchar(128) | - | - | - | 否 | |
| 取消订单时间 | cancel_time | timestamp | - | - | - | 是 | 仅取消状态的订单 |
| 取消原因 | cancel_msg | varchar(256) | - | - | - | 是 | 仅取消状态的订单 |
订单表共包括3部分信息,订单信息,收货人信息,配送信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z67KnkeK-1602499867229)(./img/取消订单.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xnc9V4mQ-1602499867256)(./img/已完成订单.png)]
支付流水表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 订单id | order_id | bigint(20) | - | 是 | - | 否 | |
| 支付工具id | payment_type | tinyint(1) | - | - | - | 否 | 银行卡支付,白条支付,关联 |
| 第三方订单号 | platform_order_id | varchar(128) | - | - | - | 否 | 第三方支付流水订单号,退款用 |
| 订单总额 | order_total | decimal(10,2) | - | - | - | 否 | |
| 实付金额 | pay_amount | decimal(10,2) | - | - | - | 否 | |
| 京豆数 | pay_bean | decimal(10,2) | - | - | - | 是 | |
| 优惠券 | coupon | decimal(10,2) | - | - | - | 是 | |
| 优惠券id | coupon_id | bigint(20) | - | - | - | 是 | 用来区分使用的是哪张优惠券,退款用 |
| 红包 | red_packet | decimal(10,2) | - | - | - | 是 | |
| 京贴 | subsidy | decimal(10,2) | - | - | - | 是 | |
| 礼品卡 | gift_card | decimal(10,2) | - | - | - | 是 | |
| 礼品卡id | gift_card_id | bigint(20) | – | – | – | 是 | 用来区分多张礼品卡,退款用 |
| 税费 | tax | decimal(10,2) | - | - | - | 否 | |
| 返现 | refund_cash | decimal(10,2) | - | - | - | 是 | |
| 返京豆数 | refund_bean | decimal(10,2) | - | - | - | 是 | |
| 支付时间 | pay_time | timestamp | - | - | 当前时间戳 | 否 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1YeuchB-1602499867259)(./img/已取消订单.png)]
退货/售后服务单表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 订单id | order_id | bigint(20) | - | 是 | - | 否 | |
| 支付流水id | pay_id | bigint(20) | - | 是 | - | 否 | 在退款的时候,需要查询到支付方式,金额等 |
| 商品id | sku_id | bigint(20) | - | - | - | 否 | 确认具体退款的商品 |
| 订单类型 | type | tinyint(1) | - | - | - | 否 | 0-退货,1-售后 |
| 申请数量 | sku_num | bigint(20) | - | - | 1 | 否 | 申请售后商品的数量 |
| 申请时间 | sub_time | timestamp | - | - | - | 否 | 提交申请的时间,即记录创建时间 |
| 提交申请原因 | question_describe | varchar(1024) | - | - | ‘’ | 否 | |
| 退款方式 | refund_way | tinyint(1) | - | - | - | 否 | 9-原返 |
| 商品退回方式 | pickware_type | tinyint(1) | - | - | - | 否 | 7-客户送货,8-上门取件 |
| 退货快递单号 | pickware_no | varchar(256) | - | - | - | 否 | 退货订单需要记录退货快递单号 |
| 联系人 | contact_name | varchar(256) | - | - | - | 否 | |
| 联系人手机号 | contact_phone | varchar(128) | - | - | - | 否 | |
| 退款总额 | refund_price | decimal(10,2) | - | - | - | 否 |
由于服务单和进度是一对多的关系,所以建了服务单进度表,该表只展示已提交申请后的进度。
| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 服务单id | afs_id | bigint(20) | - | 是 | - | 否 | |
| 阶段名称 | status_name | bigint(20) | - | - | - | 否 | 供货商审核,京东收货,退款,完成 |
| 阶段完成内容 | status_msg | varchar(1024) | - | - | ‘’ | 是 | |
| 进度更新时间 | create_time | timestamp | - | - | - | 否 | 记录新的服务状态产生的时间 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgRRr3Sf-1602499867261)(./img/退款订单.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yUWFhRjK-1602499867263)(./img/进度详情.png)]
2.5.6促销京东商城目前有5大促销分类:单品促销 ,赠品促销,套装促销 ,总价促销,折扣促销。这里给大家介绍下比较常见的总价促销和折扣促销。
折扣促销表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 促销名称 | promo_name | varchar(32) | - | - | - | 否 | |
| 促销开始时间 | begin_time | varchar(32) | - | - | - | 否 | |
| 促销结束时间 | end_time | varchar(32) | - | - | - | 否 | |
| 宣传语 | slogan | varchar(256) | - | - | - | 否 | |
| 备注信息 | comment | varchar(1024) | - | - | - | 否 | |
| 活动链接 | link | varchar(256) | - | - | - | 否 | |
| 优惠力度 | rate | decimal(10,2) | - | - | - | 否 | 折扣比率 |
| 是否需要人工审核 | need_manual_check | tinyint(1) | - | - | - | 否 |
总价促销表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 促销名称 | promo_name | varchar(32) | - | - | - | 否 | |
| 促销规则类型 | favor_mode | tinyint(2) | - | - | - | 否 | 总价促销活动类型 |
| 促销开始时间 | begin_time | varchar(32) | - | - | - | 否 | |
| 促销结束时间 | end_time | varchar(32) | - | - | - | 否 | |
| 店铺活动链接地址 | link | varchar(256) | - | - | - | 否 | |
| 订单额度 | quota | decimal(10,2) | - | - | - | 是 | 根据促销活动类型不同确认值 |
| 加价金额 | plus | int(8) | - | - | - | 是 | |
| 减价金额 | minus | int(8) | - | - | - | 是 | 满减、每满减类型 |
| 优惠力度 | rate | decimal(10,2) | - | - | - | 是 |
1.促销规则类型:可选值:满赠(0),满减(1),每满减(2),满赠加价购(5),满M件减N件(6),M元任选N件(13),M件N折(15),满减送(元)(16)
2.订单额度:
-
满M件减N件或M件N折 时为M的值,单位件,只支持正整数;
-
M元任选N件时为M的值,单位元,支持小数点后一位,例:9.9元;
-
满减送时为订单满金额,单位元,只支持正整数;
3.加价金额:加价金额,只支持正整数;(只满减送有效,且为可选项,该字段设置了值,必须送赠品)
4.优惠力度:
- 满M件减N件、M元任选N件时为N的值,单位件,只支持正整数;
- M件N折时为N的值,单位折,支持小数点后一位,例:8.5折;
- 满减送不支持此字段,除满减送之外其它促销为必填项。
需求说明:
加订单规则,支持以下几种总价促销优惠方式:
满M件减N件(如:满5件减1件,M的值为3至20之间的整数,N为正整数,值最小为1,最大为M的三分之一),
M元任选N件(如:99元任选3件,N的值为2-5之间的整数),
M件N折(如:2件8折,M的值为1-8之间的整数,N的值大于等于5,小于10,支持一位小数),
满减送(如:满100减10元、满100赠商品、 满100加10赠商品、满100减10赠商品、满100减10加5赠商品,此类促销应满足以下规则:
1、送赠品或者减价格必须有一个;
2、设置加价金额后必须设置赠品;
3、如果设置赠品,赠品京东价必须大于加价金额,小于满金额;
4、减金额必须小于等于订单额度的百分之八十;相关字段暂不支持设置多个值。)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pIt20J2z-1602499867274)(./img/首页促销.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ma6Dzxq6-1602499867275)(./img/详情.png)]
促销活动SKU关系表| 含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
|---|---|---|---|---|---|---|---|
| 自增id | id | bigint(20) | 是 | - | - | 否 | 自增id |
| 促销id | promo_id | bigint(20) | - | 是 | - | 否 | |
| sku id | sku_id | bigint(20) | - | 是 | - | 是 | |
| 促销类型 | promo_type | tinyint(2) | - | - | - | 否 | 1:单品促销 4:赠品促销 6: 套装促销 10:总价促销 12:折扣促销 |
| sku绑定类型 | bind_type | tinyint(1) | - | - | 1 | 否 | 1:主商品 2:赠品 4:附件 |
| 京东价格 | jd_prices | decimal(10,2) | - | - | - | 否 | |
| 赠品数量 | num | tinyint(1) | - | - | - | 是 | 赠品赠送数量,只能送1-3个 |
| 套装排序 | sort | varchar(32) | - | - | - | 是 | 套装商品展示次序 |
1.赠品数量:赠品赠送数量,只能送1-3个。(只对赠品促销有效)
2.套装排序:相同商品的SKU上次序必须一致。(只对套装促销、总价满赠类促销有效)
需求说明:
添加参加促销的SKU,一个促销最多支持1000个SKU,当基于套装促销添加SKU时,最多可设置3个商品的SKU,并且相同商品的次序要一致;
当基于赠品促销添加SKU时,赠品SKU只能是1-5个,每个赠品只能赠送1-3个,赠品的总价应低于主商品中的最小京东价。
3.拓展及总结以上数据库表结构,是在概念建模和逻辑建模两个阶段产生的数据库表,依照关系型数据库创建的规范(如3NF)来进行设计数据模型,解决数据冗余,确保数据完整性、有效性、一致性。
在物理建模阶段,可以根据业务需求,对上述数据库表进行数据拆分或修改,提升操作数据的效率。因此,可以从以下3点进行京东商城数据库表的优化:
1.SPU表中,因为京东商城展示商品的时候是展示3级列表,为了更好地显示,可以设计3级类别属性,即cid1, cid2, cid3。
2.SPU参数表中,如果去掉spu_id字段,直接把这个数据保存到商品的SPU表中,就只剩param_id和value字段了,刚好能组成一个键值对,用json类型数据存储在SPU表中,添加一个通用规格参数属性。同理,特有规格参数与SKU关联,在SPU表中也添加一个特有规格参数属性,则也可以实现该功能。这种实现方式,可以少了一张SPU参数表。
3.SPU表中,可以对该表进行垂直拆分,将商品描述,包装清单,售后服务,价格说明,能效说明这几个字段提出来一张表(spu详情表),这张表中的数据都比较大,为了不影响主表的查询效率所以拆分出这张表。
以上京东商城的数据建模,只涉及到了用户和商品,一些主功能的内容,可能存在很多功能细节的遗漏,大家有疑问或建议后续都可以提出来。另外关于店铺、物流和其他一些功能业务都没有分享到,有兴趣大家可以共同讨论研究。
关于外键:
在物理建模阶段,我们会考虑数据库开发、维护的安全性、稳定性及成本等因素。所以对于一般用户量大,并发度高的系统,会根据实际需求去决定是否保留外键关系,因为外键的使用对性能有一定影响。
有外键之后,当做一些设计外键字段的增、删、更新操作后,需要触发相关操作去检查,而不得不消耗资源;另外,外键还会因为需要请求对其他表内部加锁而容易出现死锁情况。
所以可以把对数据一致性的控制放到事务中,用代码逻辑去控制,也能分担一些应用服务器的压力。
关于自增主键:
关于自增主键,数据量大的表,到后期不好分库分表,而且不同表生成全局唯一的自增主键,是很困难的,可能会存在自增主键重复的情况,因此可以依靠一些算法,或者引入id生成服务等等。
数据建模只有指导思想,没有标准答案,要符合所在组织的业务特点,还需要考虑性能,后期扩展,维护等多方面,需要不断进化,不断完善。



