3.关系模型
大纲
- 简介
- 概念讲解
- ER模型到关系模型的映射
简介
- 关系模型最早由IBM提出
- 因为其简介特性和数理依据,受到广泛关注
- 它采用的“关系”模型,是数学中的一种概念,看起来就像表格
概念介绍
- 在 R(A1, A2, ..., An)中,R 为 relation name ; (A1, A2, ..., An) 表头叫做 relation schema 模式
- 每列代表一个属性
- 每行等于一个元组,即一个记录
![image]()
- 每个表格单元存储一个属性值
- Domain,表示为 dom(Ai),表示每个属性的定义域(取值范围)
![image]()
![image]()
- 主键用下划线表示,用来唯一指代实体的属性(们)
- 外键
- 一个 relation 中的 foreign key 外键用来指引另一个 relation 中的一个记录。因为是用来“指引”,所以该 foreign key 一定就是所指引的 entity 的主键
![image]()
- 一个 relation 中的 foreign key 外键用来指引另一个 relation 中的一个记录。因为是用来“指引”,所以该 foreign key 一定就是所指引的 entity 的主键
- 如上图
- Student-id 在关系 Student 中是一个主键
- Student-id 在关系 Take 中是一个外键
- Course-id 在关系 Course 中是一个主键
- Course-id 在关系 Take 中是一个外键
- (Student-id,Course-id)在 Take 中是一个主键
ER模型到关系的映射
- ER 模型用在一开始设计数据库
- ER 模型映射出关系模型,后续在数据库上的操作(建表等)是基于关系模型
- 后续编写在数据库上的操作语句(譬如查询、更新等),其逻辑上的推演通常是基于关系模型的
- 譬如我们要找出成绩好的学生,看到下面这个 relation,我就知道该查询的过滤条件为 GPA > 某常数
![image]()
映射的一般 ER-diagram
- 映射如下的 ER-diagram 到 relational model
步骤一:处理强实体集
- 对每个强实体:
- 创建一个包含其所有属性的 relation R
- 选取 primary key
![image]()
![image]()
- 创建相应的 relationship:
- 对于一个衍生的属性,怎么办
- 可以选择创建相应的属性在 Relation 中
- 优点:方便查询
- 缺点:一疏忽就会造成数据不一致。例如公司地点,改变某某就职公司属性的时候需要注意改变该属性
- 可以选择不创建相应属性
- 优点:避免数据不一致
- 缺点:查询该属性需要额外的操作。例如,根据其公司名字再到公司表里去找到其地址
- 可以选择创建相应的属性在 Relation 中
- 对于复合属性,怎么办
- 把该复合属性分解,每个子属性作为一个单独属性加入到 relation 中
- 例如,address.city, address.street, address.country.
- 对于多值属性,怎么办
- 创建多一张表,表里的每行表示 xx 拥有 号码 xxx
- 例如,创建表 PhoneTable (eid, phone)
步骤二:处理弱实体集
- 对每个弱实体:
- 创建关系表 R ,囊括其所有属性
- 额外再加若干个属性,即其 owner entity 的主键
- 弱实体集的主键为 owner entity 的主键和它自己的部分键 partial key
![image]()
步骤三:处理一对一关系集
- 对每个二元一对一关系,R:T --- S
- 选择二者之一,譬如把 T 的 primary key 加入到 S 的 relation 中
- 如果 S 是全部参与,T 不是,选择 S 加入 T 的 key 是更好的做法
- 若关系 R 也有属性,则一并加入
![image]()
![image]()
- 把 EMPLOYEE 的 eid 加入到 department 的 relation 中,改名 mgr_id
- 把关系属性 start_date 一并加入
![image]()
- 为什么:产生空值与否的问题,如下图
![image]()
- 也可以把两个 entity 的 relations 直接合并,两个 entity 跟他们的 relationship 一并表示
- 如果两个都全部参与,则上述做法合适
- 上述做法
- 优点:不用创造新 relation
- 缺点:如果没有全部参与,会产生 null value
- 另一种做法:创建一个新的 relation:
![image]()
步骤四:一对多关系处理
- 对每个一对多关系 R :T --- S
- 把 T 中的主键加入到 S 的关系中,作为外键
- 把该 relationship 的属性也加入 S 的关系中
![image]()
![image]()
- DEPARTMENT 关系模式的主键 dnumber 作为外键包含在 EMPLOYEE 关系模式中
![image]()
- 为什么选择将 “一” 加入到 “多” 中
![image]()
- 显然上面的冗余
- 对于递归关系,怎么办
- 对于 SUPERVISOR ,将 EMPLOYEE 的主键作为外键包含在 EMPLOYEE 中,将其命名为 super_id
- 即,把 supervisor 的 employee 的 id 加入到 supervisee 方的 relation 中,改名为 supervisor_id
![image]()
- 另一种方法
步骤五:多对多关系处理
- 对每个二元多对多关系R:A --- B
![image]()
- 为 R 单独创建一个 relation S,然后把 A 跟 B 的主键作为属性放到 S 中,作为外键,这两个主键合起来就是 R 的主键
![image]()
步骤六:非二元关系处理
- 对于每个多元(参与的 entity 大于 2 )的 relationship,创建一个新的 relation S,并把相应 entity 的 primary keys 加入到该 relation 中作为属性
- 一般来说,该多元关系的主键,为参与entity主键的并集。
- 然而,如果存在many-to-1 relationship 的约束的话,是可以用相应entity的主键作为这个relationship的主键
结果


对于类层级结构(Class Hierarchy)
- 考虑下图作为例子
![image]()
- 两种选择
- 分别为每个类创建一个 relation
- 只创建两个关系(前提是该 Hierarchy 具有覆盖约束)
- 分别为每个类创建一个 relation
- 上面两种选择中,第一种更通用
- 第一种的缺点:维护多一个 relation;查询的时候需要更多操作
- 第二种的优点:查询方便;缺点:如果没有 disjoint constraint,Employee的属性会被重复存储,浪费空间




























浙公网安备 33010602011771号