实体关系模型(Entity-Relationship Model,简称 ER图)可以描述实体以及实体之间的关系,是实际需求与数据库之间的桥梁。很多人写了多年的代码,依然把握不准实体之间的关系,不太会画ER图,那么看这篇文章就够了。本文将结合具体实例,帮你深入理解实体关系模型(什么是实体关系模型),并手把手教你如何画实体关系模型(画ER图),以及如何将ER图转化为数据库库表结构。

实体关系模型

在进行功能设计时,我们需要理清涉及到哪些实体(或者叫对象)以及他们之间的关系。比如有个需求是,实现用户购买商品的需求,这是电商平台、外卖平台以及卡券系统等的一个核心功能。对需求进行分析:这里边涉及到实体就是用户和商品,其关系是“购买”。对于“购买”这个关系,一个用户可以购买多个商品,一类商品可以支持多个用户买。

将上述实体和关系用图来表示,就是ER图。具体可以表示为如下:

  • 实体:用户、商品;
  • 关系:购买;关系类型为:多对多。
用户购买商品实体关系模型

从图中可以看出,实体关系模型主要由三个组件组成,分别是:属性、实体和关系。实体用矩形表示,属性用椭圆表示,关系用菱形表示,通过连线表示实体与属性、实体之间以及关系与属性之间的联系。

  • 实体(Entity)实体是具有明确边界、可区分的事物或对象,在现实世界中可被唯一识别的实体集中的一个成员。
  • 属性(Attribute)属性是实体的性质或特征,用以描述实体的特征信息。
  • 关系(Relationship)实体之间的链接,描述它们之间的语义联系。
实体、属性和关系图

理解这么多,差不多你已经掌握了大部分实体关系模型的概念,但是在转换为数据库的设计时,还需要按照数据库设计三范式的第三范式规范,对ER图进行调整。

如何画ER图

画ER图工具众多,只要能画线框图的工具都可以,比如draw.io、Excalidraw等,当然你也可以选用mermaid等直接通过代码生成出来(虽然它的线条和上述不一样,但是含义是相同的)。画ER图的具体步骤:

第一步:画出实体[及属性]

在业务需求开发中,实体往往就是对应物理世界的一个实物(用户、商品),当然有时候可能是抽象的一个东西(比如菜单、订单之类的)。总之,就是找到现实中的对应物,然后作为实体,先画出来。实体的属性是可选项,为了ER图更加简练,可以不画出属性,通过文字描述之类的进行说明。

绘制ER图第一步

属性的描述格式如下:

tb_user(user_id, user_name,...)

第二步:确定关系

有了实体之后,确定实体之间的关系,确定两件事:第一,两个实体是否有关系,这个比较好判断。第二,如果有关系,那么他们之间的关系是一对一、一对多还是多对多的。这里有个技巧:假设有两个实体A和B,需要回答如下问题来确定两个之间的关系:一个A可以对应x个B,一个B可以由y个A对应。

举例说明:对于用户和商品之间的关系,一个用户可以购买多个商品,一个商品可以由多个用户购买,所以用户和商品之间是多对多的关系。在比如用户和订单之间的关系,一个用户可以创建多个订单,一个订单只能有一个用户创建,所以用户和订单之间的关系就是一对多。

确定了关系之后,将实体之间有关系的进行连线,并在横线上标注对应关系,即在连接线上方写上1、n、m之类的。

绘制ER图增加关系

第三步:调整优化

基于现有的设计,购买表里可以存储用户ID、商品ID用于记录用户购买了哪些商品,但是如果用户购买了多次,每次购买了多个商品,将无法区分是那次购买的了,因此需要在购买表中增加一个购买批次。细想一下,购买批次也包含多个信息,比如下单时间、批次状态、批次总金额等等,如果全部存入购买表将导致购买表不符合第三范式的要求,因此我们在此引入订单的概念,以此来替代购买这层关系。经过调整后,将会有三个实体:用户、商品和订单,而后用户和订单之间是1:n的关系,订单和商品之间是多对对的关系。

完整ER图

可能有人会有疑惑,那用户和商品之间有关系吗?答案是:没有直接关系,因为我们不会在用户表里存商品任何信息,也不会在商品表里存用户任何信息,它们之间的关系是通过“订单”这个实体实现了间接关联,用户通过下单来购买商品,商品则通过订单销售给用户。

经过上述三个步骤,我们基本上就可以得到一个满意的ER图了。而后就可以根据ER图,把数据库设计完成。

ER图到数据库表结构的转换

库表结构设计的好坏,直接关系到你代码好不好写,甚至影响到代码和架构的质量。通常来说,将ER图转换为数据库表结构,一个实体对应一个数据库的表,而后关系转化为表结构时,有个基本规则:

  • 一对一关系可以用一张表存储;
  • 一对多关系可以用两张表存储,在“多”对应的表中存储“一”的主键进行关联;
  • 多对多关系需要用三张表存储,分别为两张实体表和一张关系表,当然也可能是多张关系表。

因此,将上述绘制的ER图转化为数据库的表结构如下所示。其中,三个实体用户、商品和订单对应三张表。然后,用户和订单之间是1:n的关系,所以在订单表中存了一个user_id,这样从用户角度出发,可以找到他的所有订单;从订单角度出发,也可以找到用户是谁。最后,订单和商品之间是一个多对多的关系,所以多出来一个“订单详情表”,表中存了order_id和goods_id的对应关系,我们可以用订单号找到所有的商品。

tb_user(user_id, user_name, ...) --- 用户表
tb_goods(goods_id, goods_name, goods_price,...) --- 商品表
tb_order(order_id, user_id, order_time, ...) --- 订单表
tb_order_detail(order_detail_id, order_id, goods_id, user_id,...) --- 订单详情表

总结

ER图为我们在业务需求和数据库设计架起了一座桥梁,可以将需求中的实体和关系描述清楚,以便于后续数据的组织以及代码的编写。本文通过“用户购买商品”这个真实案例,说明了实体以及实体之间对应关系,以及用ER图来表示实体以及关系,最后将ER图转换为实际的数据库表结构设计。本文为深入理解实体关系模型和应用此模型进行数据库设计提供了参考,希望对读者有所帮助。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注