一般地, 我们在对某个现实需求建模时, 需要执行的流程是: 首先从现实问题中总结出现实需求 (需求的汇集和分析), 将需求提炼成某种更抽象和精确的模型, 使用高级数据模型创建数据库的 概念模式 (Conceptual Schema
), (概念设计, Conceptual Design
) 并最终从这个模型得到可直接在 DBMS
上运行的数据库实现. (这一步也称为 逻辑设计 Logical Design
) 基于这个特定的数据库实现, 再在此基础上进行其他的优化和功能补足 (物理设计 Physical Design
).
本课程所教授的建模方法以 对象-实体模型 为概念模式, 以 SQL
为逻辑模式, 建模流程可以基本简化为: 提取需求 - 基于对象-实体模型构造 E-R
表并规范化 - 使用 SQL
实现数据库设计.
在上一节中我们已经知道, 对象-实体模型的核心思想是将现实世界的事物抽象为具备 属性 的不同 对象, 并且不同 对象 之间通过 关系 相联.
举例来说, 对象 就如同句子中的名词/主语/谓语, 而修饰它的形容词就等价于 属性. 最后, 关系 又可以视为 动词, 描述对象之间的行为或交互.
下面我们举例说明如何使用 E-R
模型建模:
考虑对一个零售公司的销售业务进行建模. 我们已知的事实是:
从中我们首先可以直接看出, 我们需要对 4 4 4 种实体进行建模: Customer
, Product
, Order
和 Employee
.
对现实问题进行建模通常需要我们结合实际情况做出主观的假设. 进一步地, 我们可以基于假设和对给定信息的推断得出不同实体所应当被建模的属性:
需要注意的是: E-R
模型要求每个实体类型都要有一个可用来唯一确定实体实例的 码. 因此, 在构建 E-R
模型时, 我们就用 *
表示不同实体类型的 码.
在完成对实体类型的建模后, 我们就需要考虑实体之间的关系. 一般而言, 从给定的信息中提取或推断实体类型之间的关系是很自然的事. 在本例中, 我们就可以直观地看出, Customer
和 Order
之间必存在一个关系 Places
, 也就是 “下订单”.
在 E-R
表中, 我们通过 将表示不同实体类型的表用实线相连 来标记这些实体之间存在 关系. 我们一般还会把关系名写在实线上方, 从而便于理解.
需要注意的是, 在对关系建模时, 除了标明 关系影响或包含的对象, 关系名 以外, 我们还需要明确标示关系的 基数约束, 也就是标明 某关系一侧可以出现的最大和最小实体数.
在本课程中, 我们使用 鸦脚标记法 标记 E-R
表中每个关系的基数约束. 如:
其语法规则如下:
下面讨论一些在构造 E-R
图时可能会遇到的问题和一些特殊记法.
首先, 双向的一对一关系可能会造成死锁问题, 这样的关系在对关系进行建模时要注意避免:
此外, 我们可以在 E-R
图中表示两个实体类型之间的多个不同关系:
形式上, 我们还可以在构造 E-R
图时就提前指定每个实体类型表中的 主键 和 外键, 但在该步骤中由于我们 仍然处在概念建模阶段, 尚未开始数据库的具体实现, 因此 不能提前添加属性域和对属性的约束:
我们可能会需要对 本身不具备码 的 弱实体类型 (见本文 定义 1.2.4
) 建模. 由于 弱实体类型的存在依赖于某个正常的实体类型 (因为只有通过某个由正常实体类型的主键和弱实体类型的属性组成的复合键才能对它的实例进行唯一确定), 因此任何弱实体类型必然与某个正常实体类型存在某种关系. 在 ER
表中, 弱实体类型的标记语法如下:
同样地, 在对某些实体类型建模时, 我们可能需要对它的一些属性的表示方式进行取舍. 具体选择什么表示方式取决于实际问题的需要.
E-R
模型到数据库模式 (Schema
) 间的转换在得到 E-R
图后, 我们需要将其转换为数据库模式 (本质上还是关系模式中定义的规则):
在转换过程中一般地有以下的一一对应关系:
E-R
图中的每个 实体类型 被转换为数据库模式中的一个用表格 (table
) 表示的关系, 其原因是我们的数据库基于关系模型, 而在关系模型中, 原来的 “实体” 也需要被建模成关系.
每个实体类型中的 属性 被相应地转化为对应关系 (数据库模式中被建模成关系的实体类型) 中的属性.
一般地, 用 *
表示的 码 被转换为对应关系的主键.
E-R
图中用实线表示的, 实体类型之间的关系现在用外键或联表表示.
具有码的强对象类型会被直接转换为关系. 需要注意的是, 在从 E-R
图转换到数据库模式时, 我们需要补足每个关系中每个属性的 约束, 默认值 和 主键/外键标示:
由于弱类型本身没有码, 在转换时弱类型对应的关系中会新增一个身为外键的属性, 该属性就是它的设计中复合主键的一部分: 其父关系类型的主键.
下面考虑对 关系 的转换:
若某两个实体类型之间存在 一对一关系 (1-to-1 relationship
), 则在转换时要在父类型 (Parent Node
) 对应的关系中新增一个属性, 该属性作为这个关系的 非空外键, 指向子类型的主键.
比如, Customer
和 User
是一一对应关系, Customer
是父类型, 则在表示 Customer
时就需要添加指向 子类型 User
表主键的非空外键 userID
.
若某两个实体类型之间存在 一对多关系 (one-to many relationship
), 则在转换时要在子类型 ('many' side
) 对应的关系中新增一个属性, 该属性作为这个关系的 可空外键, 指向父类型的主键.
比如, Customer
和 Order
是一对多关系, Order
是子类型, 则在表示 Order
时就需要添加指向 父类型 Customer
表主键的外键 custID
.
多对多关系不能被直接转换, 需要构造联合类型(Joining Entity
).
REFERENCE:
Powerdesigner数据库建模–概念模型–ER图
数据库中的Schema是什么?
Super key in DBMS
Candidate key
SQL–超键、候选键、主键、外键的认识和区分
Wikipedia: Armstrong’s axioms
数据库第一二三范式到底在说什么?
【数据库系统】第十一讲 数据建模之思想与方法
数据库概念(基数、关系模式的概念)
One-to-Many Relationship