??作者简介:小北编程(专注于HarmonyOS、Android、Java、Web、TCP/IP等技术方向)
🐳博客主页: 开源中国、稀土掘金、51cto博客、博客园、知乎、简书、慕课网、CSDN
🔔如果文章对您有一定的帮助请👉关注?、点赞👍、收藏📂、评论💬。
🔥如需转载请参考【转载须知】
“实体关系模型 (或ER模型) Entity Relationship Diagram描述了特定知识领域中相关的感兴趣事物。基本ER模型由实体类型 (对感兴趣的事物进行分类) 组成,并指定实体 (这些实体类型的实例) 之间可以存在的关系。”
——维基百科
实体关系图里的实体,通常指的是实体类别,并不是具体的一个实体。比如我们说的客户,就是指具有相似性的所有客户,而不是指具体的一个客户。实体关系图里的关系,也是对实休这一类别之间的关系描述。
```mermaid
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
```
实体名称通常是大写的,尽管对此没有公认的标准,并且在Mermaid中不是必需的。
实体之间的关系由线表示,末端标记表示基数。Mermaid使用最流行的乌鸦脚(crow’s foot)符号。乌鸦的脚直观地传达了它所连接的实体的许多实体的可能性。
ER图可以用于各种目的,从没有任何实现细节的抽象逻辑模型到关系数据库表的物理模型。在ER图上包含属性定义可能很有用,以帮助理解实体的目的和含义。这些不一定需要详尽无遗;通常一小部分属性就足够了。Mermaid允许根据其类型和名称进行定义。
```mermaid
erDiagram
CUSTOMER ||--o{ ORDER : places
CUSTOMER {
string name
string custNumber
string sector
}
ORDER ||--|{ LINE-ITEM : contains
ORDER {
int orderNumber
string deliveryAddress
}
LINE-ITEM {
string productCode
int quantity
float pricePerUnit
}
```
E-R图也叫做实体-关系图(Entity Relationship Diagram),是一种表示实体类型、属性和关系的方法,用来描述现实世界的概念模型。
E-R图由以下3个要素构成:
实体(Entity)
:数据模型中的数据对象(即数据表),用长方体来表示,每个实体都有自己的实体成员(entity member)或者说实体对象(entity instance),如学生实体里包括张三、李四等。属性(Attribute)
:实体所具有的属性,如学生具有姓名、学号、年级等属性,用椭圆形表示,属性分为唯一属性( Unique Attribute)和非唯一属性,唯一属性指的是唯一可用来标识该实体实例或者成员的属性,用下划线表示,一般来说实体至少有一个唯一属性关系(Relationship)
:用于表现实体与实体之间的联系,如学生的实体和成绩表的实体之间有一定的联系,每个学生都有自己的成绩表,这就是一种关系,关系用菱形来表示。实体关系图主要涉及的关系类型有四种:一对一(1:1
)、一对多(1:N
)、多对一(N:1
)和多对多(N:N
)。四种类型分别为:
一对一(1:1
)关系:
一对多(1:N
)关系:
多对一(N:1
)关系:
多对多(N:N
)关系:
关系的存在性用最小基数来表示,即一个实体在一个联系中的存在性。存在性在转换成逻辑模式后表现为某个属性是否可以为空值,空值为不明确的值,在数据库管理系统中用 NULL 表示。
一般地,关系有如下几种存在性:
强制存在
:连线上划“1”
,表示最小的基数为1。如果联系一端的实体的实例对于该联系的其他实体的实例必须存在,则称该实体为强制的。可选存在
:连线上划“0”
,表示最小基数为0。如果联系一端的实体的实例对于该联系的其他实体的实例不要求一定存在,则称该实体为可选的。未知存在
:连线上不划“1”
或“0”
,表示目前不知道是强制还是可选的。ER图的Mermaid语法与PlantUML兼容,并带有扩展名来标记该关系。每个语句由以下部分组成:
<first-entity> [<relationship> <second-entity> : <relationship-label>]
<第一个实体> [<关系> <第二个实体> : <关系标签>]
其中:
first-entity
是实体的名称。名称必须以字母开头,可以包含数字,连字符和下划线。relationship
描述了两个实体相互关联的方式。见下文。second-entity
是另一个实体的名称。relationship-label
从第一个实体的角度描述关系。PROPERTY ||--|{ ROOM : contains
此语句可以理解为属性包含一个或多个房间,并且一个房间是一个且仅一个属性的一部分。您可以看到这里的标签是从第一个实体的角度来看的:一个属性包含一个房间,但是一个房间不包含一个属性。当从第二实体的角度考虑时,等效标签通常非常容易推断。(有些ER图从两个角度都标记了关系,但这里不支持,因为这通常是多余的)。
只有声明的first-entity
部分是强制性的。这使得可以显示没有关系的实体,这在迭代构造图时可能很有用。如果指定了语句的任何其他部分,则所有部分都是强制性的。
每个语句的relationship
部分可以分解为三个子部件:
基数是一个属性,它描述了另一个实体的多少元素可以与所讨论的实体相关。在上面的示例中,PROPERTY
可以具有与其相关联的一个或多个ROOM
实例,而ROOM
只能与一个PROPERTY
相关联。在每个基数标记中有两个字符。最外面的字符表示最大值,最里面的字符表示最小值。下表总结了可能的基数。
值(左侧) | 值(右侧) | 含义 |
---|---|---|
|o | o| | 0或1个 |
|| | || | 1个 |
}o | o{ | 0到多个 |
}| | |{ | 1到多个 |
别名
左侧值 | 右侧值 | Alias for |
---|---|---|
one or zero | one or zero | 0或1 |
zero or one | zero or one | 0或1 |
one or more | one or more | 1 或 更多 |
one or many | one or many | 1 或 更多 |
many(1) | many(1) | 1 或 更多 |
1+ | 1+ | 1 或 更多 |
zero or more | zero or more | 0 或 更多 |
zero or many | zero or many | 0 或 更多 |
many(0) | many(1) | 0 或 更多 |
0+ | 0+ | 0 或 更多 |
only one | only one | 恰好一个 |
1 | 1 | 恰好一个 |
关系可以分类为可识别或不可识别,分别用实线或虚线呈现。当所讨论的实体之一没有另一个实体就无法独立存在时,这是相关的。例如,一家确保人们驾驶汽车的公司可能需要存储有关NAMED-DRIVER
的数据。在建模时,我们可能会从观察到CAR
可以由许多PERSON
驾驶的实例开始,并且一个PERSON
可以驾驶许多CAR
——两个实体都可以在没有另一个实体的情况下存在,因此这是一种非识别关系,我们可能会在Mermaid中指定其为:PERSON }|..|{ CAR : "driver"
。请注意关系中间的两个点,这将导致两个实体之间绘制虚线。但是,当这种多对多关系被解析为两个一对多关系时,我们观察到,如果没有PERSON
和CAR,NAMED-DRIVER
就不可能存在——这种关系可以识别,并且可以使用 - 来指定,这将转换为实线:
```mermaid
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON ||--o{ NAMED-DRIVER : is
```
关系可以分为标识和非标识,分别用实线或虚线表示。这在涉及到一个实体没有独立存在的情况下是很重要的。例如,一家保险公司可能需要储存关于 驾驶员 的数据。在建模时,我们可能会观察到 汽车 可以被许多 人 驾驶,而 人 可以驾驶许多 汽车 - 这两个实体都可以独立存在,因此这是一种非标识关系,我们可以在 Mermaid 中指定为:"人" }|..|{ "汽车":"驾驶"
。请注意,关系中间有两个点,这将导致两个实体之间绘制出一个虚线。但是当这个多对多关系被拆分成两个一对多关系时,我们会发现 驾驶员 不能没有 人 和 汽车 存在——这些关系变成了标识性关系,会使用连字符进行指定,其对应实线:
别名
值 | 称作 |
---|---|
to | 标识 |
optionally to | 不可标识 |
关系可以分为识别或非识别,这些分别用实线或虚线表示。当所讨论的实体之一在没有另一个实体的情况下不能独立存在时,这是相关的。例如,一家为人们驾驶汽车提供保险的公司可能需要在NAMED-DRIVERs
上存储数据。在对此进行建模时,我们可能首先观察 aCAR
可以由许多PERSON
实例驱动,而 aPERSON
可以驱动许多CARs
- 两个实体可以在没有另一个的情况下存在,因此这是一种非识别关系,我们可以在代码图中指定为:PERSON }|..|{ CAR
: "driver"
. 请注意关系中间的两个点,这将导致在两个实体之间绘制虚线。但是,当这种多对多关系分解为两个一对多关系时,我们观察到 aNAMED-DRIVER
不能同时存在 aPERSON
和 a CAR
- 关系变得可识别并且将使用连字符指定,连字符转换为实线:
```mermaid
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON ||--o{ NAMED-DRIVER : is
```
可以通过指定实体名称后跟包含多个type name
对的块来为实体定义属性,其中块由 {}
分隔。例如:
```mermaid
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string registrationNumber
string make
string model
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string firstName
string lastName
int age
}
```
属性在实体框中呈现:
```mermaid
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string registrationNumber
string make
string model
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string firstName
string lastName
int age
}
```
type
和name
值必须以字母开头,并且可包含数字,连字符或下划线。除此之外,没有限制,也没有有效数据类型的隐式集合。
属性也可能定义键或注释。键可以是 “PK” 或 “FK”,用于主键或外键。注释由属性末尾的 ""
定义。注释本身不能有双引号字符。
```mermaid
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string allowedDriver FK "The license of the allowed driver"
string registrationNumber
string make
string model
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string driversLicense PK "The license #"
string firstName
string lastName
int age
}
```
Mermaid 方法渲染的实体关系图可以通过 erDiagram 进行类型声明。
Mermaid 类图支持类的定义,类名通过 || 包裹,成员可以在类内部定义,同时支持修饰符和类型元数据。
Mermaid 支持多种关系类型,可以通过 ||–o{、||–|{ 等表示一对多、多对多等关系。关系的方向和基数描述也可以清晰表示。
无论是哪个阶段,坚持努力都是成功的关键。不要停下脚步,继续前行,即使前路崎岖,也请保持乐观和勇气。相信自己的能力,你所追求的目标定会在不久的将来实现。加油!