banner
NEWS LETTER

5. E-R模型数据库

Scroll down

1. 数据库设计过程 (Design Process)

数据库设计是一个多阶段的过程,从抽象的需求分析到具体的物理实现。

  1. 需求分析 (Requirements Analysis):
    • 做什么: 充分了解潜在用户的数据库需求。
    • 例子: 为一个大学系统进行需求分析。
      • 用户需求: “我们需要跟踪学生、教授和课程。学生需要注册课程,教授需要教授课程。我们还需要记录学生的成绩。”
  2. 概念设计 (Conceptual Design):
    • 做什么: 选择一个数据模型(如E-R模型),并将需求转换为概念模式(E-R图)。
    • 例子: “学生”、“教授” 和 “课程” 都是实体。“注册” 和 “教授” 是关系
  3. 逻辑设计 (Logical Design):
    • 做什么: 将概念模式(E-R图)转换为数据库的逻辑模式(例如,关系型数据库的表结构)。
    • 例子: 将E-R图转换为 student 表、course 表和 takes (注册) 表。
  4. 物理设计 (Physical Design):
    • 做什么: 决定数据库的物理存储布局,如索引和文件组织。
    • 例子: 决定为 student 表的 ID 字段创建索引,以加快查询速度。

2. E-R模型的核心概念

E-R模型使用三个基本概念:实体集关系集属性

2.1 实体与实体集 (Entity Sets)

  • 实体 (Entity): 一个在企业中可区分于其他对象的”事物”。
    • 例子: 某个特定的学生 “张三”。
  • 实体集 (Entity Set): 共享相同属性的同类型实体的集合。
    • 例子: student (所有学生的集合)。
  • 主键 (Primary Key): 唯一标识实体集中每个成员的属性子集。

💡 如何画图:实体集

  • 使用矩形表示实体集。
  • 属性列在矩形内。
  • 主键属性加下划线
    [ student ]  
    |----------------|  
    | _ID_           |  <-- 主键  
    | name           |  
    | tot_cred       |  
    |----------------|  

2.2 属性 (Attributes)

属性是实体的描述性特性。

  • 简单属性 (Simple): 不可再分的原子值。
    • 例子: studentID
  • 复合属性 (Composite): 可分解为更小的子部分。
    • 例子: name 属性,可分解为 first_name, middle_initial, last_name
  • 多值属性 (Multivalued): 一个实体在该属性上可以有多个值。
    • 例子: instructorphone_numbers 属性,一个教授可以有多个电话号码。
  • 派生属性 (Derived): 其值可以从其他属性计算得出。
    • 例子: age 属性,可以从 date_of_birth (出生日期) 派生。

💡 如何画图:复杂属性

  • 复合属性: 使用缩进表示层级。
  • 多值属性: 使用花括号 { } 括起来。
  • 派生属性: 使用括号 ( ) 括起来。
    [ instructor ]  
    |--------------------------|  
    | _ID_                     |  
    | name                     |  <-- 复合属性  
    |   first_name             |  
    |   last_name              |  
    | { phone_number }         |  <-- 多值属性  
    | date_of_birth            |  
    | age()                    |  <-- 派生属性  
    |--------------------------|  

2.3 关系与关系集 (Relationship Sets)

  • 关系 (Relationship): 多个实体之间的关联。
  • 关系集 (Relationship Set): 同类型关联的集合。
  • 关系集的属性 (Attributes on Relationship Sets): 关系本身也可以有属性。
    • 例子: studentcourse 之间的 takes 关系可以有一个 grade (成绩) 属性。
  • 关系集的度 (Degree):
    • 二元 (Binary): 涉及两个实体集,最常见。
    • 三元 (Ternary): 涉及三个实体集。
      • 例子: proj_guide 关系,关联 instructor, student, 和 project

💡 如何画图:关系集

  • 使用菱形表示关系集。
  • 关系集的属性(如果有)从菱形引出。
(date)  
|  
|  
[ instructor ]          |               [ student ]  
|------------|          |               |---------|  
| _ID_       |--------< advisor >-------| _ID_    |  
| name       |        <         >       | name    |  
|------------|        (         )       |---------|  
  • advisor 是关系集。
  • date (学生开始被指导的日期) 是 advisor 关系集上的一个属性。

3. 约束 (Constraints)

3.1 映射基数 (Mapping Cardinality)

表示一个实体通过关系集能关联的实体数量。

  • 一对一 (One-to-one):
    • 例子: 一个学生最多管理一个储物柜,一个储物柜最多被一个学生管理。
    • 画法: 两边都是箭头 (→)。
  • 一对多 (One-to-many):
    • 例子: 一个导师可以指导多名学生;一个学生最多只能有一个导师。
    • 画法: “一”端是箭头 (→), “多”端是直线 (—)。
  • 多对多 (Many-to-many):
    • 例子: 一个学生可以选修多门课程;一门课程可以被多名学生选修。
    • 画法: 两边都是直线 (—)。

💡 如何画图:基数 (l..h)

一种更精确的表示法是 l..h (min..max)。

  • 例子: 需求:“一个学生必须有且仅有 1 个导师 (1..1);一个导师可以指导0个或多个学生 (0..*)。”
    [ instructor ]  0..* (advisor)   1..1     [ student ]  
    |------------|         <     >            |---------|  
    | _ID_       |----------<     >-----------| _ID_    |  
    | name       |         <     >            | name    |  
    |------------|         (     )            |---------|  

3.2 参与约束 (Participation)

  • 全部参与 (Total): 实体集中的每个实体都必须参与至少一个关系。
    • 例子: 每个学生都必须有一个导师。
  • 部分参与 (Partial): 实体可以不参与任何关系。
    • 例子: 部分教授可能没有指导学生。

💡 如何画图:参与

  • 全部参与: 使用双线连接到菱形。
  • 部分参与: 使用单线连接。
    [ instructor ]                     [ student ]  
    |------------|         (advisor)     |---------|  
    | _ID_       |----------<     >=======| _ID_    |  
    | name       | (部分)    <     > (全部)  | name    |  
    |------------|         (     )     |---------|  

3.3 弱实体集 (Weak Entity Sets)

  • 定义: 没有足够属性形成主键的实体集。
  • 依赖: 它的存在依赖于一个”标识”强实体集。
  • 辨别符 (Discriminator): 用于区分依赖于同一个强实体的弱实体的属性(也叫部分键)。
  • 例子: section (开课) 是一个弱实体集,它依赖于 course (课程)。sectionsec_id, semester, year 只是辨别符,它们必须结合 coursecourse_id 才能唯一标识一个 section

💡 如何画图:弱实体集

  • 弱实体集: 双矩形
  • 标识关系: 双菱形
  • 辨别符: 虚下划线
  • 弱实体集对其标识关系的参与总是全部的(双线)。
    [ course ]  
    |----------------|  
    | _course_id_    |  <-- 强实体的主键  
    | title          |  
    |----------------|  
           |  
           | (单线)  
           |  
    << sec_course >>  <-- 双菱形 (标识关系)  
    <<           >>  
           ||  
           || (双线,全部参与)  
           ||  
   [[ section ]]  
   ||================||  <-- 双矩形 (弱实体)  
   || _sec_id_       ||  <-- 虚下划线 (辨别符)  
   || _semester_     ||  
   || _year_         ||  
   ||================||  

4. 扩展E-R特性 (Extended E-R Features)

4.1 泛化与专业化 (Generalization / Specialization)

  • 专业化 (Specialization): 自顶向下。在高层实体集中定义有区别的子组。
  • 泛化 (Generalization): 自底向上。合并共享特征的低层实体集。
  • 属性继承 (Attribute Inheritance): 低层实体集继承高层的所有属性和关系。
  • 约束:
    • Disjoint (不相交): 一个高层实体最多属于一个低层子集。
    • Overlapping (重叠): 一个高层实体可以同时属于多个低层子集。
    • Total (全部): 高层实体必须属于某个低层子集。
    • Partial (部分): 高层实体可以不属于任何低层子集。

💡 如何画图:专业化/泛化

  • 使用一个ISA 三角形(“is a”)连接。
  • 例子: person (人) 是一个高层实体。instructor (导师) 和 student (学生) 是其专业化子集。instructor 继承 personID, name 等属性,并有自己的 salary (薪水)。student 有自己的 tot_credits (总学分)。
                         [ person ]  
                         |------------|  
                         | _ID_       |  
                         | name       |  
                         |------------|  
                               |  
                          /_\  <-- ISA 三角形  
                         |ISA|  
                        /_____\  
                        /     \  
                       /       \  
                [ instructor ]  [ student ]  
                |------------|  |-----------|  
                | salary     |  | tot_credits |  
                |------------|  |-----------|  

4.2 聚合 (Aggregation)

  • 定义: 一种抽象,允许我们将一个关系集(及其关联的实体)视为一个抽象的实体
  • 用途: 允许在”关系”和其他实体(或关系)之间建立关系。

💡 如何画图:聚合

  • 例子: 考虑三元关系 proj_guide (关联 instructor, student, project)。如果我们想为这个指导关系本身添加一个 evaluation (评价)。
  • 画法: 我们将 proj_guide 关系及其三个实体聚合起来(用一个大方框框住),然后让 evaluation 实体通过 eval_for 关系连接到这个聚合体上。
     +-----------------------------------------+  
     | [ instructor ]                          |  
     |      |                                  |  
     |      \----< proj_guide >----[ student ]  |  <-- 被聚合的关系  
     |           /     |     \                 |  
     |          /      |      \                |  
     |     [ project ] |                       |  
     +-----------------|-------------------------+  
                       |  
                       |  
                < eval_for >  
                <          >  
                       |  
                [ evaluation ]  

5. E-R设计决策 (Design Issues)

在建模时,你必须做出选择:

5.1 实体集 vs. 属性 (Entity Sets vs. Attributes)

  • 问题: phone_number (电话) 应该作为 instructor 的一个属性,还是一个单独的 phone 实体?
  • 决策:
    • 作为属性: 如果你只需要存储号码,可以将其设为 instructor多值属性 {phone_number}
    • 作为实体集: 如果你还想存储关于电话的额外信息(比如 location (位置) 或 type (类型)),那么最好将其建模为一个实体集 phone,并与 instructor 建立关系。

5.2 实体集 vs. 关系集 (Entity Sets vs. Relationship Sets)

  • 问题: registration (注册) 应该是一个实体,还是 studentsection 之间的一个关系?
  • 决策:
    • 作为关系: 如果”注册”只是简单地连接学生和课程,并可能带一个 grade 属性,那么它是一个多对多关系 (例如 takes)。
    • 作为实体集: 如果”注册”这个行为本身需要参与其他关系(比如 registration 实体需要关联到 payment (支付) 实体),那么就必须将其建模为一个实体集 registration

5.3 二元 vs. 非二元关系 (Binary vs. Non-Binary)

  • 问题: 涉及 A, B, C 三者的关联,是用一个三元关系 R(A, B, C) 还是用多个二元关系?
  • 决策:
    • 非二元 (三元): 当 A, B, C 必须同时出现才能描述一个事实时使用。
      • 例子: proj_guide (导师, 学生, 项目)。这三者必须捆绑在一起。
    • 二元: 当关系可以被分解时使用。
      • 例子: parents (孩子, 父亲, 母亲)。这最好用两个二元关系 father_of(孩子, 父亲)mother_of(孩子, 母亲) 来代替,因为一个孩子可能只知道父亲或只知道母亲。

6. 将E-R图转换为关系模式 (Reduction to Schemas)

这是从概念设计(E-R图)到逻辑设计(表结构)的步骤。

  1. 转换强实体集:

    • 每个强实体集转为一个独立的表,属性即为表的列。
    • E-R图: student(ID, name, tot_cred)
    • 表 (Schema): student ( ID, name, tot_cred )
  2. 转换弱实体集:

    • 转为一个表,包含其所有属性,包含其标识强实体集的主键(该主键是新表的外键,也是主键的一部分)。
    • E-R图: section (辨别符:sec_id, sem, year) 依赖于 course (主键:course_id)。
    • 表 (Schema): section ( course_id, sec_id, sem, year )
  3. 转换关系集:

    • 原则:多端合并:要在many的那一端添加另外一端的主键作为外键
    • 多对多 (M:N): 必须转为一个新的表。该表包含参与的两个实体集的主键(共同作为主键)以及关系自身的属性。
      • E-R图: studentadvisorinstructor
      • 表 (Schema): advisor ( s_id, i_id )
    • 一对多 (1:N): 不创建新表。将”一”端的主键,添加到”多”端的表中,作为外键。
      • E-R图: instructor (N) – inst_dept – (1) department
      • 表 (Schema): instructor ( ID, name, salary, dept_name ) ( dept_name 是外键)。
    • 一对一 (1:1): 也不创建新表。将任意一端的主键添加到另一端的表中(作为外键)。
  4. 转换复杂属性:

    • 复合属性: “扁平化”为多个列。
      • E-R图: name ( first_name, last_name )
      • 表 (Schema):first_name, last_name
    • 多值属性: 必须为其创建新的表
      • E-R图: instructor{phone_number}
      • 表 (Schema): inst_phone ( ID, phone_number )
  5. 转换专业化/泛化:

    • 方法1 (面向高层): 为高层实体和每个低层实体都创建表。
      • 表: person(ID, name...)
      • 表: student(ID, tot_cred)
      • 缺点: 获取完整的学生信息需要查询两个表。
    • 方法2 (面向低层): 只为每个低层实体创建表,表中包含继承的属性和自己的属性。
      • 表: student(ID, name..., tot_cred)
      • 表: instructor(ID, name..., salary)
      • 缺点: 如果一个人既是学生又是员工(重叠),name 等信息会冗余存储。

如果您喜欢我的文章,可以考虑打赏以支持我继续创作.

其他文章
目录导航 置顶
  1. 1. 1. 数据库设计过程 (Design Process)
  2. 2. 2. E-R模型的核心概念
    1. 2.1. 2.1 实体与实体集 (Entity Sets)
    2. 2.2. 2.2 属性 (Attributes)
    3. 2.3. 2.3 关系与关系集 (Relationship Sets)
  3. 3. 3. 约束 (Constraints)
    1. 3.1. 3.1 映射基数 (Mapping Cardinality)
    2. 3.2. 3.2 参与约束 (Participation)
    3. 3.3. 3.3 弱实体集 (Weak Entity Sets)
  4. 4. 4. 扩展E-R特性 (Extended E-R Features)
    1. 4.1. 4.1 泛化与专业化 (Generalization / Specialization)
    2. 4.2. 4.2 聚合 (Aggregation)
  5. 5. 5. E-R设计决策 (Design Issues)
    1. 5.1. 5.1 实体集 vs. 属性 (Entity Sets vs. Attributes)
    2. 5.2. 5.2 实体集 vs. 关系集 (Entity Sets vs. Relationship Sets)
    3. 5.3. 5.3 二元 vs. 非二元关系 (Binary vs. Non-Binary)
  6. 6. 6. 将E-R图转换为关系模式 (Reduction to Schemas)
请输入关键词进行搜索