笔记整理自 【宋红康】MySQL数据库(mysql安装/基础/高级/优化)
ER模型也叫作实体关系模型,是用来描述现实生活中客观存在的事物、事物的属性,以及事物之间关系的一种数据模型。在开发基于数据库的信息系统的设计阶段,通常使用ER模型来描述信息需求和信息特性,帮助我们理清业务逻辑,从而设计出优秀的数据库
ER 模型中有三个要素,分别是实体、属性和关系。
实体 ,可以看做是数据对象,往往对应于现实生活中的真实存在的个体。在 ER 模型中,用 矩形 来表 示。实体分为两类,分别是 强实体 和 弱实体 。强实体是指不依赖于其他实体的实体;弱实体是指对另 一个实体有很强的依赖关系的实体。
属性 ,则是指实体的特性。比如超市的地址、联系电话、员工数等。在 ER 模型中用 椭圆形 来表示。
关系 ,则是指实体之间的联系。比如超市把商品卖给顾客,就是一种超市与顾客之间的联系。在 ER 模 型中用 菱形 来表示。
注意:实体和属性不容易区分。这里提供一个原则:我们要从系统整体的角度出发去看,可以独立存在 的是实体,不可再分的是属性。也就是说,属性不能包含其他属性。
在 ER 模型的 3 个要素中,关系又可以分为 3 种类型,分别是 一对一、一对多、多对多。
一对一 :指实体之间的关系是一一对应的,比如个人与身份证信息之间的关系就是一对一的关系。
一对多 :指一边的实体通过关系,可以对应多个另外一边的实体。相反,另外一边的实体通过这个关 系,则只能对应唯一的一边的实体。比如说,我们新建一个班级表,而每个班级都有多个学生,每个学 生则对应一个班级,班级对学生就是一对多的关系。
多对多 :指关系两边的实体都可以通过关系对应多个对方的实体。比如在进货模块中,供货商与超市之 间的关系就是多对多的关系,一个供货商可以给多个超市供货,一个超市也可以从多个供货商那里采购 商品。
要设计有一定规模的应用,在项目的初始阶段,建立完整的 ER 模型非常关键 。开发应用项目的实质,其实就是 建模 。
我们设计的案例是 电商业务 ,由于电商业务太过庞大且复杂,所以我们做了业务简化,比如针对 SKU(StockKeepingUnit,库存量单位)和SPU(Standard Product Unit,标准化产品单元)的含义上,我 们直接使用了SKU,并没有提及SPU的概念。本次电商业务设计总共有8个实体,如下所示。
地址实体
用户实体
购物车实体
评论实体
商品实体
商品分类实体
订单实体
订单详情实体
其中, 用户 和 商品分类 是强实体,因为它们不需要依赖其他任何实体。而其他属于弱实体,因为它们 虽然都可以独立存在,但是它们都依赖用户这个实体,因此都是弱实体。知道了这些要素,我们就可以 给电商业务创建 ER 模型了,如图:
在这个图中,地址和用户之间的添加关系,是一对多的关系,而商品和商品详情示一对1的关系,商品和 订单是多对多的关系。 这个 ER 模型,包括了 8个实体之间的 8种关系。
(1)用户可以在电商平台添加多个地址;
(2)用户只能拥有一个购物车;
(3)用户可以生成多个订单;
(4)用户可以发表多条评论;
(5)一件商品可以有多条评论;
(6)每一个商品分类包含多种商品;
(7)一个订单可以包含多个商品,一个商品可以在多个订单里。
(8)订单中又包含多个订单详情,因为一个订单中可能包含不同种类的商品
有了这个 ER 模型,我们就可以从整体上 理解 电商的业务了。刚刚的 ER 模型展示了电商业务的框架, 但是只包括了订单,地址,用户,购物车,评论,商品,商品分类和订单详情这八个实体,以及它们之 间的关系,还不能对应到具体的表,以及表与表之间的关联。
我们需要把 属性加上 ,用 椭圆 来表示, 这样我们得到的 ER 模型就更加完整了。
因此,我们需要进一步去设计一下这个 ER 模型的各个局部,也就是细化下电商的具体业务流程,然后把 它们综合到一起,形成一个完整的 ER 模型。这样可以帮助我们理清数据库的设计思路。
接下来,我们再分析一下各个实体都有哪些属性,如下所示。
(1) 地址实体 包括用户编号、省、市、地区、收件人、联系电话、是否是默认地址。
(2) 用户实体 包括用户编号、用户名称、昵称、用户密码、手机号、邮箱、头像、用户级别。
(3) 购物车实体 包括购物车编号、用户编号、商品编号、商品数量、图片文件url
(4) 订单实体 包括订单编号、收货人、收件人电话、总金额、用户编号、付款方式、送货地址、下单 时间。
(5) 订单详情实体 包括订单详情编号、订单编号、商品名称、商品编号、商品数量。
(6) 商品实体 包括商品编号、价格、商品名称、分类编号、是否销售,规格、颜色。
(7) 评论实体 包括评论id、评论内容、评论时间、用户编号、商品编号
(8) 商品分类实体 包括类别编号、类别名称、父类别编号
(1)一个 实体 通常转换成一个 数据表 ;
(2)一个 多对多的关系 ,通常也转换成一个 数据表 ;
(3)一个 1 对 1 ,或者 1 对多 的关系,往往通过表的 外键 来表达,而不是设计一个新的数据表;
(4) 属性 转换成表的 字段 。
用户实体转换成用户表(userinfo)的代码如下所示。
商品分类实体转换成商品分类表(base_category),由于商品分类可以有一级分类和二级分类,比如一级分类有家居、手机等等分类,二级分类可以根据手机的一级分类分为手机配件,运营商等,这里我们把商品分类实体规划为两张表,分别是一级分类表和二级分类表,之所以这么规划是因为一级分类和二级分类都是有限的,存储为两张表业务结构更加清晰。
地址实体转换成地址表(user_address),如下所示
订单实体转换成订单表(order_info),如下所示,实际业务中订单的信息会非常多,我们这里做了简化。
订单详情实体转换成订单详情表(order_detail),如下所示。(用于体现多对多关系的,见下图)
评论实体转换成评论表(members),如下所示
商品实体转换成商品表(members),如下所示。
这个ER模型中的多对多的关系有1个,即商品和订单之间的关系,同品类的商品可以出现在不同的订单中,不同的订单也可以包含同一类型的商品,所以它们之间的关系是多对多。针对这种情况需要设计一个独立的表来表示,这种表一般称为中间表。
我们可以设计一个独立的订单详情表,来代表商品和订单之间的包含关系。这个表关联到2个实体,分别是订单、商品。所以,表中必须要包括这2个实体辅换成的表的主键。除此之外,我们还要包括该关系自有的属性:商品数量,商品下单价格以及商品名称
在上面的表的设计中,我们可以用外键来表达1对多的关系。比如在商品评论表sku_comments中,我们分别把user_id、sku_id定义成外键,以使用下面的语句设置外键。
外键约束主要是在数据库层面上保证数据的一致性,但是因为插入和更新数据需要检查外键,理论上性能会有所下降,对性能是负面的影响
实际的项目,不建议使用外键,一方面是降低开发的复杂度(有外键的话主从表类的操作必须先操作主表),另外是有外键在处理数据的时候非常麻烦。在电商平台,由于并发业务量比较大,所以一般不设置外键,以免影响娄据库性能
在应用层面做数据的一致性检查,本来就是一个正常的功能需求。如学生选课的场景,课程肯定不是输入的,而是通过下拉或查找等方式从系统中进行选取,就能够保证是合法的课程ID,因此就不需要靠数据库的外键来检查
在刚刚的设计中,我们也完成了把属性都转换成了表的字段,比如把商品属性转换成了商品信息表中的字段。
到这里,我们通过创建电商项目业务流程的ER模型,再把ER模型转换成具体的数据表的过程,完成了利用模型设计电商项目数据库的工作
其实,任何一个基于数据库的应用项目,都可以通过这种先建立ER模型,再转换成数据表的方式,完成数据库的设计工作。创建ER模型不是目的,目的是把业务逻辑梳理清楚,设计出优秀的数据库。我建议你不是为了建模而建模,要利用创建ER模型的过程来整理思路,这样创建ER模型才有意义。