数据库系统原理
00:00
数据库系统原理:关系模型、关系代数、函数依赖、范式理论与查询优化
1. 数据库系统概述
1.1 数据模型演进
| 模型 | 年代 | 特点 |
|---|---|---|
| 层次模型 | 1960s | 树形结构 |
| 网状模型 | 1960s | 图形结构 |
| 关系模型 | 1970s | 二维表,数学基础 |
| 对象模型 | 1990s | 面向对象 |
| NoSQL | 2000s | 非关系型 |
| NewSQL | 2010s | 兼顾关系与扩展 |
1.2 数据库系统结构
三级模式结构:
- 外模式:用户视图
- 概念模式:全局逻辑结构
- 内模式:物理存储结构
两级映象:
- 外模式/模式映象:保证逻辑数据独立性
- 模式/内模式映象:保证物理数据独立性
2. 关系模型
2.1 基本概念
- 关系:一个二维表
- 元组:表中的一行
- 属性:表中的一列
- 域:属性的取值范围
- 键:唯一标识元组的属性集
2.2 关系完整性
实体完整性:主键不能为 NULL。
参照完整性:外键必须引用已存在的主键值或为 NULL。
用户定义完整性:业务规则约束(如年龄 > 0)。
3. 关系代数
3.1 基本运算
选择(Selection):
选取满足条件的元组。
投影(Projection):
选取指定属性列。
并(Union):
两关系元组的并集(需并相容)。
差(Difference):
在 R 但不在 S 的元组。
笛卡尔积(Cartesian Product):
两关系元组的所有组合。
更名(Rename):
3.2 导出运算
交(Intersection):
连接(Join):
自然连接:
除(Division):
用于”查找包含所有…的…”查询。
3.3 关系代数示例
“查找选修了所有课程的学生”:
“查找年龄大于20的计算机系学生姓名”:
4. 函数依赖与范式
4.1 函数依赖
定义:若 中任意两个元组在属性集 上的值相同,则在属性集 上的值也相同,记为 。
Armstrong 公理:
- 自反律:若 ,则
- 增广律:若 ,则
- 传递律:若 且 ,则
推导规则:
- 合并律: 且 ,则
- 分解律:,则 且
- 伪传递律: 且 ,则
4.2 属性闭包
用途:
- 判断 是否成立:
- 求候选键: 的最小属性集
4.3 最小函数依赖集
满足以下条件的函数依赖集 :
- 每个依赖的右部是单个属性
- 不存在冗余依赖
- 每个依赖的左部无冗余属性
4.4 范式
1NF:属性不可再分。
2NF:在 1NF 基础上,非主属性完全函数依赖于候选键(消除部分依赖)。
3NF:在 2NF 基础上,非主属性不传递依赖于候选键。
BCNF:在 3NF 基础上,每个决定因素都是候选键。
范式关系:
4.5 模式分解
无损连接分解:
判定条件: 或
保持函数依赖分解:
目标:既无损连接又保持函数依赖的分解。
- 总能无损连接地分解到 BCNF
- 不一定能既无损又保依赖地分解到 BCNF
- 总能既无损又保依赖地分解到 3NF
5. 关系演算
5.1 元组关系演算
其中 是谓词公式。
示例:查找年龄大于20的学生
5.2 域关系演算
5.3 表达能力等价
关系代数 ≡ 元组关系演算(安全表达式)≡ 域关系演算(安全表达式)
6. 查询优化
6.1 查询处理流程
SQL 查询 → 解析 → 查询树 → 逻辑优化 → 物理优化 → 执行计划
6.2 逻辑优化(代数优化)
基于等价变换规则的优化:
- 选择下推:尽早执行选择操作
- 投影下推:尽早执行投影操作
- 连接顺序优化:小关系先连接
6.3 物理优化
选择操作的实现:
| 方法 | 适用条件 | 代价 |
|---|---|---|
| 顺序扫描 | 无索引 | |
| 索引扫描 | 有合适索引 |
连接操作的实现:
| 方法 | 代价 | 内存需求 |
|---|---|---|
| 嵌套循环 | 低 | |
| 排序归并 | 中 | |
| 哈希连接 | 高 |
6.4 代价模型
通常 I/O 代价是主要因素:
7. 事务管理
7.1 ACID 特性
| 特性 | 含义 | 实现技术 |
|---|---|---|
| 原子性 | 事务不可分割 | 日志(WAL) |
| 一致性 | 数据保持一致 | 约束检查 |
| 隔离性 | 事务互不干扰 | 锁/MVCC |
| 持久性 | 提交后永久保存 | 日志刷盘 |
7.2 并发问题
| 问题 | 描述 |
|---|---|
| 脏读 | 读到未提交数据 |
| 不可重复读 | 同一查询两次结果不同 |
| 幻读 | 同一查询两次行数不同 |
7.3 隔离级别
| 级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交 | 可能 | 可能 | 可能 |
| 读已提交 | 避免 | 可能 | 可能 |
| 可重复读 | 避免 | 避免 | 可能 |
| 序列化 | 避免 | 避免 | 避免 |
7.4 封锁协议
两阶段锁(2PL):
- 增长阶段:只加锁,不放锁
- 收缩阶段:只放锁,不加锁
2PL 保证可串行化,但可能导致死锁。
死锁处理:
- 超时检测
- 等待图检测
- 死锁预防(等待-死亡、伤害-等待)