banner
NEWS LETTER

2. 关系模型

Scroll down

关系模型 (Relational Model) 笔记

1. 基本概念

关系数据库是基于关系模型的,其核心是将数据组织在一系列的二维表中。

  • 域 (Domain): 属性的允许值集合,例如 customer_names, account_numbers 。每个值都是原子的,即不可再分的 。
  • 关系模式 (Relation Schema): 定义了一张表的结构,包括关系名和属性列表。
    • 示例: Customer_schema = (customer_name, customer_street, customer_city)
  • 关系实例 (Relation Instance): 特定时刻表中的数据,是一个元组(行)的集合 。
  • 元组 (Tuple): 表中的一行,代表一组相关的数据值 。
  • 属性 (Attribute): 表中的一列,代表元组中的一个特定属性 。

重要特性:
- 关系内的元组顺序无关 。
- 属性的顺序也无关紧要,通过属性名来引用 。

2. 键 (Keys)

键用于唯一标识和关联表中的数据。

  • 超码 (Superkey): 一个或多个属性的集合,其值可以唯一标识关系中的一个元组 。
  • 候选键 (Candidate Key): 最小化的超码,即移去任何一个属性后就不再是超码 。
  • 主键 (Primary Key): 从一个或多个候选键中选出的一个,用作元组的主要标识符 。
  • 外键 (Foreign Key): 一个关系中的属性(或属性集),其值引用了另一个关系的主键,用于建立表之间的联系 。
  • 参照完整性约束 (Referential Integrity): 强制要求外键的值要么必须匹配被引用关系中某个元组的主键值,要么为 NULL

3. 关系代数 (Relational Algebra)

这是一种过程化查询语言,通过组合一系列运算来构建查询。

3.1 基础运算

  • 选择 (Select - ): 选取满足特定条件的元组(行)。
    • 语法: ,其中 是选择条件,r是具体的表格
    • 示例: - 选择 instructor 表中所有在物理系的教师。
  • 投影 (Project - ): 选取特定的属性(列)。
    • 语法: ,其中 是属性列表。
    • 示例: - 从 instructor 表中选择ID、姓名和薪水这三列。
  • 并集 (Union - ): 合并两个关系的元组,并自动去除重复行。
    • 语法:
  • 差集 (Set Difference - ): 返回存在于第一个关系但不存在于第二个关系中的元组。
    • 语法:
  • 笛卡尔积 (Cartesian Product - ): 将两个关系的每一行进行组合。
    • 语法:
  • 重命名 (Rename - ): 改变关系或其属性的名称。
    • 语法: 将表达式 E 的结果重命名为 x。

3.2 附加运算 (Additional Operations)

这些运算虽然可以由基础运算组合而成,但因为常用,所以被定义为独立的运算符。

交集 (Set Intersection - )

  • 目的: 找出同时存在于两个关系(表)中的元组(行)。
  • 语法:
  • 解释: 返回的结果集中包含了所有既属于关系 又属于关系 的元组。
  • 约束: 参与运算的两个关系必须是并兼容的(即它们具有相同数量的属性,并且对应属性的域也相同)。
  • 示例: 假设有两个课程列表,一个是秋季学期开设的课程 (FallCourses),另一个是春季学期开设的 (SpringCourses)。要找出两个学期都开设的课程:
    Π_course_id(FallCourses) ∩ Π_course_id(SpringCourses)

3.2.1 自然连接 (Natural Join - ):像拉拉链一样合并信息

  • 核心思想: 把两张有共同点的表,像拉链一样合并成一张更详细的表。

  • 生活中的例子:
    假设你有两张清单:

    1. 同学名单 (instructor 表)
    2. 班级信息表 (department 表)

    instructor (教师表)
    | ID | name | dept_name |
    | :— | :— | :— |
    | 10101 | Srinivasan | Comp. Sci. |
    | 12121 | Wu | Finance |
    | 32343 | El Said | History |

    department (院系表)
    | dept_name | building |
    | :— | :— |
    | Comp. Sci. | Taylor |
    | Finance | Painter |

    这两张表的共同点dept_name(院系名称)这一列。

  • 运算过程:
    执行自然连接 instructor ⋈ department 时,数据库会:

    1. 找到两个表中同名的列 (dept_name)。
    2. instructor 表中的每一行,与 department 表里 dept_name 值相同的那一行进行“拼接”。
    3. 拼接后的新表中,dept_name 这一列只保留一个,不会重复出现。
  • 结果 (一张更详细的表):
    | ID | name | dept_name | salary | building |
    | :— | :— | :— | :— | :— |
    | 10101 | Srinivasan| Comp. Sci. | 65000 | Taylor |
    | 12121 | Wu | Finance | 90000 | Painter |

注意History 系的 “El Said” 老师没有出现在结果里,因为 department 表中没有 “History” 这一行,无法匹配。自然连接只保留能成功匹配的行。

3.2.2 除法 (Division - ÷):查找“全能冠军”

  • 核心思想: 找出那些满足了所有条件的记录。专门用来回答带有“所有”、“每一个”这类词的问题。

  • 生活中的例子:
    假设你有一个记录所有学生选课情况的表格,和一个记录了“核心必修课”的清单。

    1. 学生选课总表 (r)
    | StudentID | Course |
    | :— | :— |
    | 101 | 数学 |
    | 101 | 物理 |
    | 101 | 英语 |
    | 102 | 数学 |
    | 102 | 英语 |
    | 103 | 物理 |

    2. 核心必修课清单 (s)
    | Course |
    | :— |
    | 数学 |
    | 物理 |

    问题: 哪些学生选修了所有的核心必修课?
    运算: (学生选课总表) ÷ (核心必修课清单)

  • 运算过程:

    1. 系统先看清单 s,要求是必须同时拥有“数学”和“物理”的记录。
    2. 然后去总表 r 里检查每个学生:
      • 学生101: 选了数学吗?选了。选了物理吗?选了。✅ 满足所有条件。
      • 学生102: 选了数学吗?选了。选了物理吗?没选。❌ 不满足所有条件,被排除。
      • 学生103: 选了数学吗?没选。❌ 不满足所有条件,被排除。
  • 结果 (全能冠军的名单):
    | StudentID |
    | :— |
    | 101 |

    最终结果就是学生 101,因为只有他满足了“一个都不能少”的条件。

赋值 (Assignment - )

  • 目的: 将一个复杂的查询表达式的结果保存到一个临时的关系变量中,以便在后续的查询中重复使用。这使得复杂查询的步骤更清晰。
  • 语法: temp_relation ← expression
  • 示例: 找出所有在 “Physics” 系且薪水超过 的教师姓名。
    1. high_paid_physics_profs ←
    2. result ←

3.3 扩展运算 (Extended Operations)

这些运算提供了更强大的数据处理和计算能力。

广义投影 (Generalized Projection)

  • 目的: 允许在投影操作中进行计算或重命名列。
  • 语法:
  • 解释: 与基本投影不同,这里的 不仅可以是属性名,还可以是涉及属性、常量和算术运算符(+, -, *, /)的表达式。
  • 示例: 给所有教师涨薪10%,并显示他们的ID、姓名和新薪水。

外连接 (Outer Join)

  • 目的: 在连接操作中保留那些在另一个关系中没有匹配项的元组,用 NULL 填充缺失的属性值。
  • 左外连接 (Left Outer Join - ⟕):
    • 语法:
    • 解释: 返回两个关系自然连接的结果,并加上关系 中所有在关系 中找不到匹配的元组(右侧属性填充为 NULL)。
    • 示例: instructor ⟕ teaches 会列出所有教师,即使某个教师没有授课记录。对于没有授课的教师,course_id, sec_id 等来自 teaches 表的字段将为 NULL
  • 右外连接 (Right Outer Join - ⟖):
    • 语法:
    • 解释: 与左外连接相反,保留右侧关系 中的所有元组。
  • 全外连接 (Full Outer Join - ⟗):
    • 语法:
    • 解释: 保留两个关系中的所有元组,无论它们是否有匹配。没有匹配的部分用 NULL 填充。

4. 数据库修改

  • 删除 (Deletion): 使用差集运算 来删除满足条件的元组 。
  • 插入 (Insertion): 使用并集运算 来添加元组 。
  • 更新 (Update): 通过广义投影实现,可以对属性值进行计算和修改 。

5. NULL 值处理

  • 定义: NULL 表示值未知或不存在 。
  • 运算: 任何涉及 NULL 的算术运算结果仍为 NULL
  • 比较: NULL 值的比较结果为 unknown
  • 聚集函数: 通常会忽略 NULL 值 。

例题:找出薪水最高的员工姓名

三张表:
employee(ID, person_name, street , city)

works(ID, company_name, salary)

company(company_name,city)

分步实现:

  1. 第一步:找出所有低于最高薪水的薪水值集合。

    • 为了比较 works 表自身,我们创建两个副本并重命名:w1w2
    • 然后找出所有 w1.salary < w2.salary 的情况,并投影出 w1.salary

  2. 第二步:用所有薪水的集合减去“非最高薪水”的集合,得到最高薪水。

    • 首先获取所有薪水的集合:
    • 然后执行差集运算。

    • 此时,Max_Salary 这个临时关系里只包含一个值:最高的薪水。
  3. 第三步:利用最高薪水值,通过自然连接找到对应员工的姓名。

    • 首先找到拥有最高薪水的员工的记录(包含ID)。
    • 然后与 employee 表连接以获取姓名。

完整的关系代数表达式

如果将以上步骤合并成一个表达式,会是这样:

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

其他文章
目录导航 置顶
  1. 1. 关系模型 (Relational Model) 笔记
    1. 1.1. 1. 基本概念
    2. 1.2. 2. 键 (Keys)
    3. 1.3. 3. 关系代数 (Relational Algebra)
      1. 1.3.1. 3.1 基础运算
      2. 1.3.2. 3.2 附加运算 (Additional Operations)
      3. 1.3.3. 3.2.1 自然连接 (Natural Join - ):像拉拉链一样合并信息
      4. 1.3.4. 3.2.2 除法 (Division - ÷):查找“全能冠军”
      5. 1.3.5. 3.3 扩展运算 (Extended Operations)
    4. 1.4. 4. 数据库修改
    5. 1.5. 5. NULL 值处理
      1. 1.5.1. 例题:找出薪水最高的员工姓名
请输入关键词进行搜索