基本图形
图形 | 名称 | 含义说明 |
---|---|---|
矩形(Rectangle) | 实体(Entity) | 表示一个现实世界中的对象或概念,如“学生”、“课程”、“订单”等。每个实体通常对应数据库中的一张表。 |
菱形(Diamond) | 联系/关系(Relationship) | 表示两个或多个实体之间的关联,如“学生选修课程”。可以标注关系类型(1:1, 1:N, N:M)。 |
椭圆(Oval) 或 圆角矩形 | 属性(Attribute) | 表示实体或联系的属性(字段),如“姓名”、“年龄”、“成绩”等。主键属性通常加下划线或用其他方式标出。 |
双椭圆 或 带斜杠的椭圆 | 多值属性(Multivalued Attribute) | 表示该属性可能有多个值,如一个人可能有多个电话号码。 |
黑点椭圆 或 带“#”的椭圆 | 主键属性(Primary Key) | 表示该属性是实体的唯一标识符(主键)。 |
白色椭圆 或 带“FK”的属性 | 外键属性(Foreign Key) | 表示该属性引用另一个实体的主键,用于建立实体间的联系。 |
双重矩形(Double Rectangle) | 弱实体(Weak Entity) | 表示不能独立存在的实体,必须依赖于某个强实体存在,如“订单明细”依赖于“订单”。 |
双菱形(Double Diamond) | 弱联系(Identifying Relationship) | 弱实体与强实体之间的联系,通常用虚线箭头连接。 |
基数符号
不同风格的 ER 图会使用不同的符号表示关系的数量限制(Cardinality),常见风格包括:
Chen 风格
- 使用
(1,1)
、(0,N)
等形式直接标注在菱形旁边。 - 更偏向理论表达。
Crow’s Foot 风格
- 使用图形化的“叉”状符号表示:
|
:表示“1”O|
:表示“0 或 1”||
:表示“1 且仅 1”O<
或∞
:表示“多”
示例:
学生 1 ——–<选修>——– N 课程
箭头
实箭头
- 表示 单向的关系 或 外键引用的方向。
- 常用于表达一个表中的 外键指向另一个表的主键。
- 比如:
学生 → 专业
,表示学生的某个属性(如“专业编号”)是外键,指向“专业”表的主键。
虚箭头
- 表示 可选的引用 或 弱实体与强实体之间的依赖关系。
- 在 ER 图中,弱实体(Weak Entity)依赖于强实体(Strong Entity),这种关系常用虚线箭头表示。
- 虚线也可能表示一种逻辑上的关联,而不是强制性的外键约束。
示例:
- “订单明细”是一个弱实体,它必须依赖于“订单”这个强实体存在。
- 关系用虚线箭头从“订单明细”指向“订单”。
无箭头
- 表示 双向关系 或 多对多关系。
- 不强调谁引用谁,而是强调两个实体之间存在某种联系。
- 多对多关系通常需要通过中间的“连接表”来实现。
示例:
- 学生和课程之间是多对多关系:一个学生可以选修多门课,一门课也可以被多个学生选修。
- 这种关系通常用无箭头的连线表示,并标注为
N:N
。
判断数据库设计
判断一个 ER(实体 - 关系)图设计是否良好,主要需要从其是否准确、清晰地表达了现实世界的信息,并避免了数据库设计中常见的缺陷(如冗余)等方面进行评估。
-
避免冗余:
- 实体与属性的区分:冗余是设计中的一大问题,它不仅浪费空间,更重要的是容易导致数据不一致。一个好的 ER 图应避免将本可以用作属性的信息提升为独立的实体。
- 例如,如果制造商只有一个名称属性,并且没有其他关于制造商的信息或它不处于任何多对多或多对一关系中的“多”端,那么制造商的名称作为啤酒的一个属性可能就足够了,无需单独创建一个“制造商”实体集。反之,如果制造商有地址等非键属性,或与多个啤酒有关系,则应设计为实体集 [1]。
- 属性在多处出现:避免在多个实体或关系中重复存储同一事实。
- 例如,如果“啤酒”实体集包含“制造商名称”和“制造商地址”,而同时又有一个独立的“制造商”实体集包含“名称”和“地址”,这就会导致冗余 [1]。
- 实体与属性的区分:冗余是设计中的一大问题,它不仅浪费空间,更重要的是容易导致数据不一致。一个好的 ER 图应避免将本可以用作属性的信息提升为独立的实体。
-
正确使用实体集与属性:
- 何时使用实体集:一个“事物”应该被设计为实体集,如果它不仅仅是一个名称,或者它具有至少一个非键属性,或者它在一个多对一或多对多关系中处于“多”的一端 [1]。
- 何时使用属性:如果一个“事物”没有需要进一步描述的性质,是不可再分割的数据项,并且不能与其他实体有联系,那么它更适合作为属性 [1]。
-
限制使用弱实体集:
- 避免过度使用:初学者常会怀疑某些实体能否单独作为键,从而倾向于将所有实体集都设计为弱实体集,并依赖其他实体集来辅助标识。实际上,大多数情况下可以通过为实体集创建唯一的 ID(如学号、VIN 等)来避免弱实体集 [1]。
- 何时需要:弱实体集通常只在没有一个全局权威能够分配唯一 ID 的情况下才需要,例如在全球范围内为足球运动员分配唯一的号码是很困难的 [1]。
-
清晰和正确的语义表达:
- 命名规范:实体集、属性和关系的名称应清晰、准确地反映其在现实世界中的含义。
- 键的指定:每个实体集都必须指定一个或一组属性作为其主键,并在 ER 图中用下划线标示,以确保实体集的唯一性 [1]。
- 关系的基数(多重性):关系上的箭头应准确地表示实体集之间的基数约束(例如,一对一、一对多、多对多,以及精确为一的圆头箭头),这对应着功能依赖或多值依赖 [1]。
- 关系属性:如果某个属性的值依赖于关系中所有参与实体集的组合(而不是其中某一个),则该属性应依附于关系。例如,“销售”关系中的“价格”通常取决于特定的酒吧和啤酒,而不是单独的酒吧或啤酒 [1]。
-
适应性和可扩展性:
- 一个好的 ER 图设计应具有适应性,当系统的功能或需求发生变化时,能够以最小的修改来适应新的要求,从而降低维护成本 [1]。
转换为关系模型
https://www.cnblogs.com/yijiahao/p/11707183.html
将 ER(实体 - 关系)图转换为关系模型是一个系统化的过程,它将概念性的数据库设计图示转化为具体的表格结构,包括关系(表)、属性(列)和它们之间的键关系。这个过程遵循一系列规则,以确保数据的一致性、完整性和非冗余性 [1]。
以下是将 ER 图转换为关系图(即关系模式或表格结构)的主要原则和步骤 [1]:
-
实体集到关系(表)的转换
- ER 图中的每一个强实体集都将转换为一个独立的关系(表)。
- 实体集的所有简单属性都将成为该关系中的列(属性) [1]。
- 实体集中的键属性将成为该关系的主键,并在关系模式中标记为
PRIMARY KEY
[1]。 - 复合属性(如地址包含街道、城市、邮编)通常会被分解为多个简单属性,每个简单属性成为一个列。
- 多值属性(ER 图中不推荐直接表示,但若存在)则需要创建单独的关系来存储。
示例:
Beers(name, manf)
实体集转换为Beers(name: PRIMARY KEY, manf)
关系 [1]。Drinkers(name, addr, phone)
实体集转换为Drinkers(name: PRIMARY KEY, addr, phone)
关系。
-
关系(联系)到关系(表)的转换 关系的转换取决于其类型(多重性)和是否包含属性 [1]。
-
多对多(M:N)关系:
- 每个 M:N 关系都会转换为一个新的独立关系(表) [1]。
- 这个新关系的主键由参与该 M:N 关系的所有实体集的主键组成,这些主键在新关系中同时作为外键引用回它们各自的实体关系 [1]。
- 如果 M:N 关系本身包含属性,这些属性也将成为新关系中的列 [1]。
- 示例:
Sells
(Bars 和 Beers 之间的 M:N 关系,且有price
属性) [1]。 转换为Sells(barName: FOREIGN KEY, beerName: FOREIGN KEY, price)
,其中{barName, beerName}
组合作为Sells
表的PRIMARY KEY
[1]。
-
多对一(M:1)关系:
- M:1 关系通常不创建新的关系(表),而是通过在“多”端实体关系中添加外键来实现 [1]。
- 将“一”端实体集的主键添加到“多”端实体集所对应的关系中作为外键 [1]。
- 如果 M:1 关系本身包含属性,则这些属性也添加到“多”端实体关系中 [1]。
- 示例:
Favorite
(Drinkers 到 Beers 的 M:1 关系) [1]。Drinkers
关系会添加一个favBeer
列,作为外键引用Beers
表的name
列。Drinkers(name: PRIMARY KEY, addr, phone, favBeer: FOREIGN KEY REFERENCES Beers(name))
[1]。 这种合并可以避免冗余,并且在查询时更有效率 [1]。
-
一对一(1:1)关系:
- 1:1 关系类似于 M:1 关系,可以选择将其中一端的主键作为外键添加到另一端的实体关系中。选择哪一端取决于实际情况,例如哪一端的数据更少或更不常为 NULL。
- 如果 1:1 关系本身包含属性,则通常倾向于创建一个新的关系(表)来表示这个关系,其中包含两端实体的主键作为外键,以及关系本身的属性。
-
多元(N-ary,涉及三个或更多实体集)关系:
- 任何涉及三个或更多实体集的多元关系都将转换为一个新的独立关系(表) [1]。
- 该新关系的主键由所有参与实体集的主键组成,这些主键同时作为外键引用回它们各自的实体关系 [1]。
- 如果多元关系本身包含属性,这些属性也将成为新关系中的列 [1]。
- 示例:
Preferences
(Drinkers, Bars, Beers 之间的 3-way 关系) [1]。 转换为Preferences(drinkerName: FOREIGN KEY, barName: FOREIGN KEY, beerName: FOREIGN KEY)
,其中{drinkerName, barName, beerName}
组合通常作为Preferences
表的PRIMARY KEY
。
-
-
弱实体集(Weak Entity Set)的转换
- 弱实体集会转换为一个独立的关系(表) [1]。
- 该关系的主键由两部分组成:弱实体集自身的部分键(ER 图中带虚线的下划线属性)加上其支持强实体集的主键 [1]。
- 支持弱实体集的关系(联系)本身通常不会产生独立的关系,除非该关系自身拥有除参与实体主键以外的额外属性 [1]。
示例:
Players
(name, number) 弱实体集通过Plays-on
关系依赖Teams
(name) 强实体集 [1]。Teams
转换为Teams(name: PRIMARY KEY)
。Players
转换为Players(playerNum: PRIMARY KEY, teamName: PRIMARY KEY FOREIGN KEY REFERENCES Teams(name), playerName)
。这里的playerNum
是Players
的部分键,teamName
是其支持实体Teams
的主键,二者共同构成Players
表的复合主键。
-
子类(ISA 层次结构)的转换 对于 ER 图中的子类层次结构,有几种常见的转换方法 [1]:
-
对象导向(Object-Oriented)方式:
- 为每个子类(包括超类)创建一个关系。
- 超类关系包含所有超类的属性。
- 每个子类关系包含超类的主键(作为自己的主键和外键)以及子类特有的属性 [1]。
- 示例:
Beers(name: PRIMARY KEY, manf)
和Ales(name: PRIMARY KEY FOREIGN KEY REFERENCES Beers(name), color)
[1]。 - 优点:查询子类特定信息方便。
-
使用 NULL 值(Nulls)方式:
- 只为超类创建一个大的关系。
- 这个关系包含超类和所有子类的所有属性。
- 如果某个实体不属于某个子类,那么该子类特有的属性列的值就为 NULL [1]。
- 示例:
Beers(name: PRIMARY KEY, manf, color)
,非 Ales 啤酒的color
为 NULL [1]。 - 优点:节省空间(如果 NULL 值不多),查询所有实体类型方便。
-
ER 风格(ER Style)方式:
- 为层次结构中的每个类(包括超类和每个子类)创建一个单独的关系 [1]。
- 每个关系包含其自身的键属性以及其特有的属性 [1]。
- 示例:
Beers(name: PRIMARY KEY, manf)
和Ales(name: PRIMARY KEY, color)
。通常Ales
的name
会作为外键指向Beers.name
[1]。 - 优点:查询所有类型实体方便。
-
在转换过程中,确保为每个新建的关系都定义了合适的主键和外键,并根据需要添加其他完整性约束(如 NOT NULL、UNIQUE、CHECK 等),以保证最终关系模式的质量 [1]。