数据库系统原理期末笔记

Not just for exam.

参考:林子雨老师的《数据库系统原理》,以及《软件设计师教程》

写在前面:刻在DNA里的学生选课数据库

本章的所有实例都以学生选课数据库为基础,该数据库包括5个表:

  1. 学生表Student(Sno, Sname, Ssex, Sage, Sdept);
  2. 课程表Course(Cno, Cname, Cpno, Ccredit);
  3. 学生选课表SC(Sno, Cno, Grade);
  4. 教师表Teacher(Tno, Tname, Tsex, Tage);
  5. 授课表TC(Tno, Cno)。

每一个表的第一列都是主码。

Student

Sno Sname Sex Sage Sdept
2024001 林书凡 18 MA
2024002 李欣然 19 IS
2024003 王武义 20 CS
2024004 苏文甜 19 CS

Course

Cno Cname Cpno Ccredit
1 大数据 3 2
2 操作系统 5 4
3 数据库 5 4
4 编译原理 NULL 4
5 编程语言 NULL 2
6 数据挖掘 3 2

SC

Sno Cno Grade
2024001 1 97
2024001 2 78
2024001 3 86
2024002 2 85
2024002 3 77

Teacher

Tno Tname Tsex Tage
97001 林形文 45
97002 司马鹰松 33
97003 王明天 38
97004 马晓燕 36
97005 张勇 51

TC

Tno Cno
97001 1
97001 3
97002 2
97003 4
97004 5
97004 6
97005 6

数据库概述

关系数据库

关系运算

逻辑表达式

运算符 含义
比较运算符 > 大于
>= 大于等于
< 小于
<= 小于等于
= 等于
<> 不等于
逻辑运算符 ¬

八种关系运算

  1. 并(Union)

    • 符号:
    • 作用:合并两个关系中的元组,去除重复的元组。
    • 表示:,表示关系R和关系S的并集。
  2. 交(Intersection)

    • 符号:
    • 作用:找出两个关系中共有的元组。
    • 表示:,表示关系R和关系S的交集。
  3. 差(Difference)

    • 符号:
    • 作用:从第一个关系中移除与第二个关系中相同的元组。
    • 表示:,表示关系R中不在关系S中的元组。
  4. 选择(Selection)

    • 符号:
    • 作用:从关系中选择满足特定条件的元组()。
    • 表示:,表示从关系R中选择满足条件的元组。
  5. 投影(Projection)

    • 符号:
    • 作用:从关系中选择特定的属性
    • 表示:,表示从关系R中选择指定的属性列。
  6. 连接(Join)

    • 符号:
    • 作用:将两个关系中满足特定条件的元组合并成一个新的关系。
    • 表示:,表示关系R和关系S的自然连接。
      • 条件连接θ-连接):,其中是连接条件,可以是等比较运算符,表示基于这些条件的连接。
      • 外连接(Outer Join):当两个关系中没有完全匹配的元组时,外连接可以返回其中一个关系的所有元组,以及另一个关系中匹配的元组。如果另一个关系中没有匹配的元组,则结果中对应的字段为NULL
        • 左外连接(Left Outer Join):返回左关系(R)的所有元组,即使在右关系(S)中没有匹配的元组。如果右关系中没有匹配的元组,则结果中右关系的部分为NULL
          • 表示:Double subscripts: use braces to clarifyR \underset{A \theta B}{\Join}_{\text{L}} S 或者
        • 右外连接(Right Outer Join):返回右关系(S)的所有元组,即使在左关系(R)中没有匹配的元组。如果左关系中没有匹配的元组,则结果中左关系的部分为NULL
          • 表示:Double subscripts: use braces to clarifyR \underset{A \theta B}{\Join}_{\text{R}} S 或者
        • 全外连接(Full Outer Join):返回两个关系中任一关系的所有元组,无论另一个关系中是否有匹配的元组。如果另一个关系中没有匹配的元组,则结果中对应的字段为NULL
          • 表示:Double subscripts: use braces to clarifyR \underset{A \theta B}{\Join}_{\text{FULL}} S 或者
  7. 笛卡尔积(Cartesian Product)

    • 符号:×
    • 作用:将两个关系中的每个元组与另一个关系中的每个元组配对,形成所有可能的组合。
    • 表示:R × S,表示关系R和关系S的笛卡尔积。
  8. 除(Division)

    • 符号:÷
    • 作用:找出能够与第二个关系中所有元组配对的第一个关系中的元组。
    • 表示:R ÷ S,表示关系R中能够与关系S中所有元组配对的元组。

简单理解:

  • 选择是取行,投影是取列。
  • 自然连接中,如果两个表有相同的列名,那两个表相同列名的列,具体值也要相同,才能配对。所以左右表都有可能会删去一些不匹配的行。
  • 左外连接中,左边表的所有行都会被保留,即使右边表中没有匹配的行,此时右边表对应的位置会用NULL填充。
  • 右外连接同理。
  • 全外连接中,左右两边表的所有行都会被保留,无论是不是匹配,当有一边没有匹配时,那一边对应的位置会用NULL填充。
  • 笛卡尔积就是两个表直接不由分说地连, 大小的表A和 大小的的表B,笛卡尔积得到的表C,与连接不同。
  • 除如图:图片

关系运算的sql表示

  1. 并(Union)

    1
    2
    3
    SELECT column_name(s) FROM table1
    UNION
    SELECT column_name(s) FROM table2;
  2. 交(Intersection)

    1
    2
    3
    SELECT column_name(s) FROM table1
    INTERSECT
    SELECT column_name(s) FROM table2;
  3. 差(Difference)

    1
    2
    3
    SELECT column_name(s) FROM table1
    EXCEPT
    SELECT column_name(s) FROM table2;
  4. 选择(Selection)

    1
    2
    SELECT * FROM table
    WHERE condition;
  5. 投影(Projection)

    1
    SELECT column_names FROM table;
  1. 连接(Join)
  • 自然连接(Natural Join)

    1
    2
    SELECT * FROM table1
    NATURAL JOIN table2;
  • 条件连接(θ-连接)

    1
    2
    SELECT * FROM table1
    JOIN table2 ON condition;
  • 外连接(Outer Join)

    • 左外连接(Left Outer Join)

      1
      2
      SELECT * FROM table1
      LEFT JOIN table2 ON condition;
    • 右外连接(Right Outer Join)

      1
      2
      SELECT * FROM table1
      RIGHT JOIN table2 ON condition;
    • 全外连接(Full Outer Join)

      1
      2
      SELECT * FROM table1
      FULL JOIN table2 ON condition;
  1. 笛卡尔积(Cartesian Product)

    1
    SELECT * FROM table1, table2;
  2. 除(Division)

    1
    2
    3
    4
    5
    SELECT column_names FROM table1
    WHERE NOT EXISTS (
    SELECT * FROM table2
    WHERE table1.column = table2.column
    );

习题

学生数据库

已知数据库

  1. 学生表S(Sno, Sname, Ssex, Sage, Sdept);
  2. 课程表C(Cno, Cname, Cpno, Ccredit);
  3. 学生选课表SC(Sno, Cno, Grade);

完成:

  1. 检索选修课程名为“数学”的学生的学号和姓名。
  2. 检索至少选修了课程号为 1 和 3 的学生的学号。
  3. 检索选修了“操作系统”或“数据库”课程的学生的学号和姓名。
  4. 检索年龄在 18~20 之间(含 18 和 20)的女生的学号、姓名及年龄。
  5. 检索选修了“数据库”课程的学生的学号、姓名及成绩。
  6. 检索选修了全部课程的学生的姓名所在系。
  7. 检索选修课程包括 1042 学生所学课程的学生的学号。
  8. 检索不选修 2 课程的学生的姓名和所在系。

My answer:
打latex也太难了吧,我直接开始歪歪地手写
图片

关系数据库标准语言SQL

视图在数据字典中保存的是视图定义

关系数据库编程

关系数据库安全和保护

关系数据库的规范化理论

关系模式中可能存在的冗余和异常问题

  1. 数据冗余
  2. 不一致性
  3. 插入异常
  4. 删除异常

    函数依赖

    定义

  5. 函数依赖:设 为任一给定关系,如果对于 中属性 的每一个值, 中的属性 只有唯一值与之对应,则称 函数决定 ,或 函数依赖于 X,记作 。其中,X 称为决定因素。反之,对于关系 中的属性 ,若 不能函数决定 Y,则其符号记作
  6. 平凡的函数依赖:设 是一个函数依赖,若 ,则称 是一个平凡的函数依赖
  7. 完全函数依赖:设 是一个函数依赖,并且对于任何 都不成立,则称 是一个完全函数依赖,记作
  8. 部分函数依赖:设 是一个函数依赖,但不是完全函数依赖,则称 是一个部分函数依赖,记作
  9. 传递函数依赖:设 是一个关系模式,,如果 ,且 ,则称 传递函数依赖
  10. 候选码:设 为任一给定关系模式, 为其所含的全部属性集合, 的子集,若有完全函数依赖 ,则 的一个候选码
  11. 主属性和非主属性:包含在任何一个候选码中的属性为主属性,否则为非主属性。

理解

  1. 普通函数依赖(X→Y)
    想象你的身份证号码(X)就像一把万能钥匙,它能直接确定你的姓名(Y)、性别、出生地。只要知道身份证号,其他信息都能唯一确定。
    例如:学号→姓名,就像每个学号对应唯一的学生。

  2. 平凡依赖 vs 非平凡依赖

    • 平凡就像「已知父亲名字,自然知道家族姓氏」(因为姓氏已经是父亲名字的一部分)
    • 非平凡像「快递单号与包裹信息」,单号能唯一确定收件人的电话(例如单号 SF123456 对应电话 13800001111),但电话不是单号的子集,这也是​​非平凡函数依赖
  3. 完全依赖 vs 部分依赖
    完全依赖就像「用完整钥匙开锁」:

    • 成绩完全依赖(学号+课程号)组合,单独学号或课程号都不够

    部分依赖像「用半截钥匙就能开锁」:

    • 如果课程名称只依赖课程号(而课程号是主键的一部分),就是部分依赖
  4. 传递依赖(连锁反应)
    学号→系号→系主任,系主任像被「间接遥控」确定。这会导致数据冗余(多个学生重复存储系主任信息)

  • 候选码就像「能开所有锁的最小钥匙组合」:

    • 比如(学号+课程号)组合才能确定成绩,单独一个都不行
  • 主属性是所有候选码中的零件:

    • 如果候选码是学号,那么学号就是主属性;如果候选码是(学号+身份证号),两者都是主属性

范式

第一范式(1NF)

如果关系模式 的每一个 属性对应的域值都是不可再分的,称模式 属于第一范式,记作 。若数据库模式 中的每个关系模式都是 ,则数据库模式

最基本的要求,就是表中的每个属性都不可再分。例如,学生信息表中,每个学生的姓名、年龄、性别等都是不可再分的。

第二范式(2NF)

如果关系模式 ,并且每个非主属性都完全函数依赖于 的码,则

不能有部分依赖。例如,在选课表中,学生成绩应该依赖于学号和课程号的组合,而不是单独依赖学号或课程号。

第三范式(3NF)

关系模式 R 中若不存在这样的码 、属性组 及非主属性 ,使得 成立,则称

例如,学生表中的成绩不能依赖于学生的姓名,因为姓名不是码。

Boyce-Codd范式(BCNF)

,而且R中没有任何属性传递函数依赖于R中的码,则关系模式

第四范式(4NF)

了解一下就可以了。

第五范式(5NF)

了解一下就可以了。

理解

  1. 1NF(基础版)
    要求:每个字段都是最小单元,不能拆。
    错误示范:把「联系电话」写成 “13800001111,13800002222”(应拆分成多行)

  2. 2NF(消灭半吊子依赖)
    必须消灭部分依赖。比如选课表中:

    • 错误:把课程名称和成绩都放在同一张表(课程名称只依赖课程号,不依赖学号)

    • 正确:拆分成「选课表(学号+课程号+成绩)」和「课程表(课程号+课程名称)」

  3. 3NF(斩断连锁依赖)
    禁止传递依赖。比如学生表里直接存系主任名字:
    • 错误:学生表包含系号→系主任
    • 正确:拆分成「学生表(学号+系号)」和「院系表(系号+系主任)」
  4. BCNF(加强版3NF)
    连主属性都不能有传递依赖。举个极端例子:
    • 假设每个老师只教一门课,每门课有多个老师
    • 错误表:(老师ID,课程)主键是老师ID,但课程→教室(课程不是主键)
    • 正确:拆分成「老师-课程表」和「课程-教室表」

举个综合例子(学生选课系统):
原始混乱表
| 学号 | 姓名 | 课程号 | 课程名 | 成绩 | 系名 | 系主任 |
|—-|—-|—-|—-|—-|—-|—-|
| 001 | 张三 | C01 | 数学 | 90 | 计算机系 | 李主任 |

问题分析:

  1. 课程名只依赖课程号(违反2NF)
  2. 系主任依赖系名,系名依赖学号(传递依赖,违反3NF)

助记小漫画(但是记的可能不是数据库知识点)

</details>

规范化后:

  • 学生表(学号,姓名,系名)3NF

  • 课程表(课程号,课程名)2NF

  • 选课表(学号,课程号,成绩)2NF

  • 院系表(系名,系主任)3NF

这样修改后,更新系主任信息只需要修改院系表中的一个位置,避免了数据冗余和更新异常。

模式分解

习题

2021上半年软考 42题

给定关系R(U,F),其中U={A,B,C,D,E,H},F={(A→B,B→DH,A→H,C→E)}。关系有( ),F中( )。

问题1:

  • [ ] A. 1个候选码A
  • [ ] B. 2个候选码A、B
  • [x] C. 1个候选码AC
  • [ ] D. 2个候选码A、C

问题2:

  • [ ] A. 不存在传递依赖,但存在冗余函数依赖
  • [ ] B. 既不存在传递依赖,也不存在冗余函数依赖
  • [ ] C. 存在传递依赖A→D和A→H,但不存在冗余函数依赖
  • [x] D. 存在传递依赖A→D和A→H,并且还存在冗余函数依赖