探究京东的数据建模
1.数据建模介绍
1.1 什么是数据建模?
数据建模指的是对现实世界各类数据的抽象组织,确定数据库需管辖的范围、数据的组织形式等直至转化成现实的数据库。 将经过系统分析后抽象出来的概念模型转化为物理模型后,在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,是一对多
购物车:
- 一个商品可以被添加到多个购物车中,一个购物车可以添加多个商品,是多对多
订单:
- 一个购物车可以生成多个订单,是一对多
- 一个订单包含一个支付流水,是一对一
2.4 E-R 图
2.5 表结构
2.5.1用户
用户表
含义 | 字段名 | 类型 | 主键 | 外键 | 默认值 | 可以为空 | 说明 |
---|---|---|---|---|---|---|---|
自增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:需要本地根据设备判断,显示支付方式入口,默认是都不支持。
银行卡属