跳转至

第6章 使用E-R图进行数据库设计

作者: 弗畔

6.1 设计过程概览

本小节仅讨论设计数据库模式(database schema)。

设计阶段

  • 用文字描述需求:这需要数据库设计者与领域专家和用户深入沟通,其产出是用户故事。

  • 概念设计(conceptual design):使用实体-联系模型,将需求转化为对数据库的图形化表述(概念模型)。需要定义数据库的实体、实体属性、实体间的联系、实体和联系上的约束。

此外,还需要在功能需求规格说明(specification of functional requirement)中定义在数据上的操作。进而检查概念模型是否满足需求。

  • 逻辑设计(logical design):将概念模型映射为数据模型,即将E-R模型映射为关系模型。

  • 物理设计(physical design):指明数据库的物理特征,包括文件组织格式和索引结构。

6.2 E-R模型

实体(entity)

实体是指抽象或具象的事物,用属性来标识。

属性

实体有一组属性。我们可以用属性来区分不同实体。相同实体组成实体集(entity set)。和在数据库里一样,我们会选择部分属性作为主码来唯一标识实体。

我们称属性对应的值域为域(domain)。如果将属性及其取值描述为二元组(attribute, value),那么实体可以表述为这种二元组的集合。

null

如果属性取值未知,可以填为null。

属性的分类

  • 简单和复合属性(composite attributes)。复合属性是指可以被划分为更小属性的属性(component attributes)。若不能被划分,则为简单属性。

image-2022080252517211

  • 单值和多值属性。多值属性是指一个属性可以保存一组值,比如一个用户可以有多个字符串(多个电话号码)存储在phone_number中。表示为{phone_number}。

  • 派生属性(derived attributes):每次查询时通过计算其它属性得到值的属性。例如age,每次查询时计算当前时间与出生日期的差即可。其表示为age()。派生属性不作存储。

属性的符号表示

本节介绍E-R模型中实体属性的符号表示。

image-2022080212647692

  • 主键:在属性名下划线
  • 复合属性:用缩进表示组合关系
  • 多值属性:{属性名}
  • 派生属性:属性名()

联系(relationship)

实体间的联系就是若干个实体集笛卡尔积的子集。我们称这个集合为联系集\(R\)。设联系集\(R\)涉及的实体为\(E\),我们称\(E\)参与联系集\(R\)

联系集的元素被称作联系实例(relationship instance)。

实例在联系中扮演的功能被称为角色(role)。通常可以省略。但在自环的联系(即实体集与自己的联系)中,角色是重要的。例如课程集的先修关系。

image-20220610220922724

联系可以具有描述性属性。即每个联系实例能够具有属性。但联系实例必须能够仅由参与实体唯一标识(见6.3.码)。

image-20220610221003374

对某个联系集,参与实体集的个数被称作该联系集的度(degree)。例如上图存在一个二元联系集,它的度为2。

如果实体集中的每一个实体都参与了实体集,我们称该实体集在联系中的参与是全部的。否则为部分参与。

在设计E-R模型时,要明确有些信息是可以用联系集来实现的,而不一定要保存在实体的属性里。这通常会使实体间的关系更清晰。例如学生所属的院系。

6.3 约束

映射基数(mapping cardinality)

映射基数表示一个实体通过一个联系集能关联到的实体的个数,这等价于一个实体能够参与的联系实例的个数。

本节只讨论二元联系集R。R涉及实体集A和B。根据映射基数,A与B的关系可被分为四类。

  • 一对一:实体集A、B中的一个实体仅能参与一个联系实例。
  • 一对多:A中的一个实体能参与多个联系实例,B中的一个实体仅能参与一个联系实例。
  • 多对一:A中的一个实体仅参与一个联系实例,B中的一个实体能够参与多个联系实例。
  • 多对多:A中的一个实体能关联多个B的实体,反之亦然。

image-20220802154007799

码(key)

基于以下2点,我们可以用参与实体的主码来唯一标识联系实例。

  • 实体可以用主码表示
  • 实体可以唯一标识联系实例

即,用参与实体的主码的并集A来唯一标识联系实例。

对于联系实例的描述性属性,我们可以直接与A求并。

如果不同实体的主码有重名属性,用“实体.”区分。如果实体名称相同,则用角色区分。

6.4 E-R图

基本结构

  • 分成两部分的矩形代表实体集。上半部分代表名称,下半部分代表属性。主码用下划线标识。
  • 菱形代表联系集。
  • 线段将实体集连接到联系集
  • 虚线将描述性属性连接到联系集
  • 双线表示实体集完全参与联系集
  • 双菱形表示连接弱实体集的标志性联系集(见后文叙述)

image-20220802162536249

映射基数

image-20220405214430077

非二元的联系集

我们规定:在非二元的联系集中,至多只能存在一个箭头。它表示:其它实体集的一个组合只能参与一个联系实例。

另一种表示

这里的数字就是映射基数的范围。也就是说:一个学生只能参与一个关系,而一个教授能够参与多个关系。于是,这是一个一对多的联系。

image-20220405214843272

属性

image-2022080212647692

用缩进表示复合属性;用{}表示多值属性;用()表示派生属性,就像是一个函数。

角色

在到联系的实线上标注名称,以说明角色。

image-20220610220922724

弱实体集

为避免冗余,我们允许实体集没有主码。没有足够属性形成主码的实体集被称作弱实体集(weak entity set)。有主码的实体集被称作强实体集(strong entity set)。

弱实体集A需要加上一些属性构成主码,这些属性需要在另一个实体集B中。我们称:A的标识实体集(identifying entity set)为B,B拥有(own)它所标识的实体集A。A与B的联系被称作标识性联系(identifying relationship)。需要注意,弱实体集可以有多个标识实体集

弱实体集的主码由标识实体集的主码和弱实体集自身属性组成。后者被称为分辨符(discriminator attributes)。

需要注意,这种标识性联系是为了构成主码,那么,从A到B的联系应该是多对一的。

弱实体集可以参与其它联系,也可以作为其它弱实体集的属主(owner)。

我们有时也可以将弱实体集表示为标识实体集的一个多值复合属性。这取决于弱实体集的属性是否复杂,以及是否与其它实体集有联系。

弱实体集的符号表示

弱实体集的分辨符以虚下划线标明,而不是实线。关联弱实体集和标识性强实体集的联系集以双菱形表示。

image-20220802154839196

6.5 转换为关系模式

本节讨论如何将E-R图转换为关系模式。我们约定:E表示E-R图的实体集,R表示E-R图的联系集,S表示关系模式的一张表。

具有简单属性的强实体集

E的一个实体对应S的一个元组。我们只需要根据E建立一张表即可。属性和主码可以直接照搬。

具有复杂属性的强实体集

  • 复合属性

将复合属性拆分,只保留叶子属性

  • 多值属性

为多值属性建立关系表A。A的属性包括该多值属性和实体集的主码。A的主码可以是所有属性,之后可以根据实际情况缩小范围。此外,A需要建立外键,即参照实体集对应的表B。

显然,B不应保留多值属性。如果B只剩下主码,我们应当删去B以及外键关系,只保留A。

  • 派生属性

通过方法或函数实现。

弱实体集的表示

弱实体集为A,标识实体集为B。那么,A对应的关系模型S的属性由A的属性和B的主码构成。同时,S需要建立外键,即参照B的主码。需要注意,这一外键关系是级联删除的。

联系集的表示

联系集仍然会成为一个关系模型S。其属性是联系集的描述性属性和参与实体集的主键的并。我们需要建立外键约束。来自哪个实体集的属性就参照该属性集对应的表。

我们根据联系的特征选取主码:

  • 对于多对多关系,参与实体集的主码的并集作为S的主码。
  • 对于一对一的二元关系,任取一个实体集的主码作为S的主码。
  • 对于一对多的二元关系,选择“多”(即一个实体只参与一个联系的实体集)主码作为S的主码。

如果重名,则改名。

关系模式的化简

冗余

弱实体集与标识实体集之间的联系集对应的模式是冗余的,不必给出。

合并

在处理多对一关系(例如,A与B是多对一关系)时,我们可以把联系集对应的表合并到A对应的表里,生成新表A'。这个新表的属性为AB和A表属性的并集。

一对一时,任取一个实体对应的表与联系集对应的表合并。

因为有可能只是部分参与,我们可以使用null。也就是说,与A合并后,B的属性可能取null.

6.6 拓展的E-R特性

特化、概化与属性继承

image-20220802160141712

特化(specialization)实际上是一种设计过程。即先提出一个较为抽象的实体集,再细化,加一些差异性的属性。

概化(generalization)是一个自底向上的设计过程。

在这个过程中,我们规定存在属性继承和联系继承。即高层的属性和联系关系都被低层继承。

其它概念

  • 部分概化:存在高层实体没有低层实体
  • 全部概化:高层实体都有低层实体
  • 不相交:高层实体至多属于一个低层实体集,对应上图的合并箭头
  • 重叠:高层实体可以属于多个低层实体集,对应上图分开的箭头

聚集(aggregation)

我们可以将一个联系集及它所涉及的实体集抽象地视为一个实体集。我们称之为聚集。这主要是为了减少存储冗余。以下图为例,如果evaluation需要与instructor、project、student建立联系eval_for,就会再存储一遍在联系集proj_guide已经存储过的信息。于是,我们希望能够将联系集视作更高抽象的实体,即聚集。

聚集的含义是:建立一个多元组,这个多元组包括聚集内部参与联系集的所有实体集。

image-20220802160556069

概化的关系模型表示

这个很简单,为每一个实体建表即可,其属性包括继承属性,并继承主码定义。此外,还需要定义外键:低层实体集的表需参照高层实体集的表。

如果概化是不相交且完全的,我们可以只建立低层实体集的关系模型。

聚集的关系模型表示

聚集内部有一个联系集A。聚集外联系集B的属性是A的主码、其它参与实体集的主码以及描述性属性,前两者构成B表主码。之后,转换聚集内部的联系集和实体集即可。自然,联系集A对应的表是多余的,它被B对应的表包含。

6.7 实体-联系的设计问题

实体集 vs 属性

对于一个对象而言,如果我们希望保存额外信息,我们会建立为实体集。反之可以作为其它实体集的一个属性。

常见错误:

  • 将一个实体集的主码作为另一个实体集的属性,而非联系。
  • 将主码作为联系集的属性。

实体集 vs 联系集

描述实体间行为时采用联系集。

二元 vs n元

只要添加足够多的辅助实体集、联系集,我们可以将n元联系转化为二元联系。

当然,我们还需要增加标识属性,以将(a,b,c)转化为(a,e),(b,e),(c,e)。

image-20220802161253204

当然,有些n元联系会更自然,并且n元联系上的约束可能无法转化为二元约束。

联系集属性的设计

在一对多和一对一联系中,联系集的属性可以合并到实体集中。其规则和选择主码的规则类似:在一对多中,放到“多”的实体集中;在一对一中,任取一个即可。这是因为描述性属性需要与某一个联系实例绑定,而只有部分实体集的主键能够唯一确定联系实例。

但对于多对多联系,则只能以联系集的描述性属性表示。

本站总访问量

评论