Lazy loaded image
🗃️数据库系统原理
字数 9737阅读时长≈ 25 分钟
2026-5-25
2026-10-22
By BarryZed
目录
数据库引论数据管理发展的几个阶段人工管理阶段文件系统阶段数据库系统阶段数据库体系结构物理独立性逻辑独立性结构独立性分布独立性事务的四个特性(ACID)模式数据模型基本概念码(Key)常用的数据模型层次结构(树)网状结构(有向图)关系模型实体-联系方法(E-R模型)关系型数据库结构及形式化定义关系关系的完整性约束实体完整性参照完整性用户自定义完整性关系代数的基本运算并差广义笛卡尔积选择(Selection)投影(Projection)关系代数的扩展运输交连接(Join)除(Division)关系型数据库标准语言SQL' ' 与" " 表的创建、删除与修改常见约束条件列级约束与表级约束表的结构修改索引的建立与删除数据查询单表查询聚集函数group by 与 having 连接查询嵌套查询集合查询数据修改插入数据修改数据删除数据视图创建视图删除视图数据库安全与保护数据库的安全性数据库系统的安全概述存取控制审计数据库的完整性完整性约束条件数据库完整性约束按约束对象属性级完整性元组级完整性关系级完整性按检查时机静态完整性约束动态完整性约束完整性控制外码是否接受空值在被参照关系中删除元组级联删除(Cascaded)受限删除(Restricted)置空值删除(Nullified)在参照关系中插入元组受限插入(Restricted Insert)递归插入(Cascaded Insert)修改被参照关系中的被参照属性值级联修改(Cascaded)受限删除(Restricted)置空值删除(Nullified)数据库并发控制并发控制概述事务指令并发操作数据的不一致性丢失修改(Lost Update)脏读(Dirty Read)不可重复读(Non-repeatable Read)幻读(Phantom Read)具体差别可串行性可串行性(Serializability)事务的隔离级别封锁(Locking)封锁类型封锁粒度(Lock Granularity)封锁协议(Locking Protocol)保证数据 “一致性” 的封锁协议——三级封锁协议保证并行调度 “可串行性” 的封锁协议——两段封锁协议(Two-Phase Locking,2PL)活锁(Livelock)和死锁(Deadlock)活锁(Livelock)死锁(Deadlock)数据库恢复技术故障的种类事务故障(Transaction Failure)系统故障(System Failure)介质故障计算机病毒恢复的实现技术数据转储(Data Dump / Backup)登记日志文件为保证数据库是可恢复的,日志文件必须遵守以下两个原则:恢复策略事务故障的恢复系统故障的恢复检查点技术关系型数据库设计理论数据依赖对关系模式的影响插入异常(Insertion Anomaly)删除异常(Deletion Anomaly)修改异常(Update Anomaly)关系模式的规范化函数依赖(Functional Dependency,FD)平凡函数依赖非平凡函数依赖完全函数依赖(Full Functional Dependency)部分函数依赖(Partial Functional Dependency)码候选码与主码超码(Super Key)主属性(prime attribute)其他属性范式第一范式(1NF,First Normal Form)第二范式(2NF,Second Normal Form)第三范式(3NF,Third Normal Form)BCNF(Boyce–Codd Normal Form,巴斯-科德范式)多值依赖与第四范式多值依赖(Multivalued Dependency,MVD)第四范式(4NF,Fourth Normal Form)

数据库引论

数据管理发展的几个阶段

人工管理阶段

  • 数据和程序混在一起
  • 数据不保存
  • 没有专门的管理软件
  • 计算结束后数据消失

文件系统阶段

  • 数据以文件形式保存,可长期存储
  • 冗余大
  • 共享性差
  • 不同程序有各自的文件

数据库系统阶段

  • 数据结构化
  • 冗余低
  • 独立性强
  • 支持并发控制
  • 支持安全与完整性约束
程序 → DBMS → 数据库
实现独立性的核心机制:三级模式结构 + 两级映像
外模式(用户视图) 概念模式(整体逻辑结构) 内模式(物理存储)
+
外模式 ←→ 概念模式

数据库体系结构

物理独立性

物理存储方式改变,不影响逻辑结构和应用程序

逻辑独立性

逻辑结构改变,不影响外模式和应用程序

结构独立性

数据库内部结构的变化,不影响应用程序的使用方式
数据结构变化,但接口不变

分布独立性

数据存在哪里(单机或多机分布),不影响应用程序

事务的四个特性(ACID)

特性
英文
核心一句话
原子性
Atomicity
要么全做,要么全不做
一致性
Consistency
执行前后数据必须合法
隔离性
Isolation
多事务互不干扰
持久性
Durability
提交后永久保存

模式

数据库中有哪些表、字段、约束、关系,以及这些数据应该怎么组织
说白了就是一张蓝图,里面有很多表、字段、约束等等
外模式就是视图
内模式是指硬件上具体的存储方式
一个数据库只能有一个内模式
一个表可能有多个文件组成

数据模型

基本概念

码(Key)

标识唯一实体的属性或属性集

常用的数据模型

层次结构(树)

无法描述事物间复杂的联系,特别是多对多

网状结构(有向图)

关系模型

分量:元组中的一个属性值(不可再分,表中不能有表)

实体-联系方法(E-R模型)

E-R图:
实体:矩形(表)
属性:椭圆(表的字段)
联系:菱形(表与表之间的关系)

关系型数据库

结构及形式化定义

关系

笛卡尔积
每一种数据的每一个和其他的每一种数据的全组合
举例
Sno
Sname
1
A
2
B
Cno
Cname
10
Math
20
CS
笛卡尔积:
Sno
Sname
Cno
Cname
1
A
10
Math
1
A
20
CS
2
B
10
Math
2
B
20
CS

关系的完整性约束

数据库完整性的定义一般由 SQL 的 DDL(Data Definition Language)语句来实现。它们作为数据库模式的一部分存入 数据字典(Data Dictionary) 中

实体完整性

主属性(即主码中的属性)不能为空
关系模型中以主码作为唯一性标识

参照完整性

外码或取空值,或在被参照的表中能找到记录
外码
别的表的主码或唯一键,在这个表当字段用
作为本表与另一表之间的桥梁,作为参照关系
比如都有学号在表2中作为外码
  • 就能从表1中找到该学生的名字、性别等个人属性,从表2中找到选修课、成绩等学业属性;
  • 如果修改表2中的学号,则会将该行的学业属性连接到其他的学生
可以取空值
表示暂时没有关联

用户自定义完整性

给属性限制,确保值符合逻辑

关系代数的基本运算

并

差

左右两个集合必须同结构

广义笛卡尔积

选择(Selection)

从表中选择满足条件的行

投影(Projection)

从表中挑出某些列,并将行按行去重
去重原则:这一整行是否完全相同

关系代数的扩展运输

交

连接(Join)

笛卡尔积 + 选择
本质公式
等值连接(Equi-Join)
连接条件是等于
自然连接(Natural Join)
自动找同名属性进行匹配,并自动去掉重复列
外连接(Outer Join)
左/右外连接
在右侧表/左侧表中找不到的记录用NULL补齐
全外连接
左右都保留,没有的用NULL补齐

除(Division)

找“对 S 中所有元素都满足关系的 R 的主键”
S的属性要是R的子集
主键 = R 中“没有出现在 S 里的属性” or 被“保留下来作为结果”的那一部分属性
例子
R
学生
课程
A
DB
A
OS
B
DB
B
OS
C
DB
S
课程
DB
OS
R中选择了S里所有课程的学生
结果
学生
A
B

关系型数据库标准语言SQL

关系操作通过关系操作语言来实现,关系操作语言的特点是集合操作,操作的对象和结果都是关系。

' ' 与" "

' ' :字符串
" " :标识符(别名、表名)

表的创建、删除与修改

使用 char() 作为数据类型时,不够长的值将用空格补足长度,会导致 like 搜索时无法正确返回指定结尾数据

常见约束条件

约束
含义
PRIMARY KEY
主键(唯一+非空,UNIQUE + NOT NULL)
NOT NULL
不能为空
UNIQUE
唯一
DEFAULT
默认值(不可引用本表的其他列、其他表或视图)
CHECK
条件限制
FOREIGN KEY
外键(需单独声明,不能直接写在列后面,references的必须是主码或者有unique属性的列)
复合主键
constraint
给复合主键、check 、外键等约束条件起名

列级约束与表级约束

对比点
列级约束(Column-level)
表级约束(Table-level)
写法位置
列后
表末尾
作用范围
单列
多列
是否能写外键
不能
标准
是否能复合主键
不行
可以

表的结构修改

添加列
删除列
修改列
删除约束
有名字
没名字
删除表

索引的建立与删除

索引时数据库为表中的某些列建立的一种“快速查找结构”
建立索引
删除索引

数据查询

基本结构
根据 where 子句的条件表达式,从 from 子句指定的基本表或视图中找出满足条件的元组,再按 select 子句中的目标列表达式选出元组中的属性值,最后形成结果表。
完整执行顺序:

单表查询

全选
student * :指student表里所有列
count(*) :所有列
基本查询
一般 select 的第二列为表达式,比如查询年龄
也可以是别名
会在查询出的表格中把表头的 sname 变为姓名
排序查询
去重查询
仍然是按整行去重
in
= OR 的简写
↑ = ↓
可以改为 not in
模糊查询( like )
通配符:
% :任意字符(0~∞个)
B% :B开头的
_ :1个字符
B_r :B+某+r
可以改为 not in
若想要寻找带有通配字符的值,需使用 escape
↑ = ↓
以上关键字也可以放在 where 的条件中,但是 where 不能使用别名,因为 where 的执行在 select 前
where 中不能使用聚合函数
NULL :只能用 is null 或者 is not null

聚集函数

可直接放在 select 后,作为搜索结果
函数
作用
COUNT
计数
SUM
求和
AVG
平均值
MAX
最大值
MIN
最小值
统计行数
统计某列非空行数
除 count(*) 外,其他所有聚集函数均忽略 NULL

group by 与 having

group by :按条件分组
having :按条件过滤组别,可以使用聚合函数
HAVING 一定在 GROUP BY 之后,WHERE 一定在 GROUP BY 之前

连接查询

where 子句中的连接查询
直接在 where 里面写列的表达式
自身连接
给同一张表起两个别名,自身查找
from 子句中的连接查询
内连接
外连接
left outer join 、right outer join 、full outer join
交叉连接(笛卡尔积)

嵌套查询

一个 SQL 语句里“套娃”另一个 SQL 语句
子语句在 select 、from 、where 里均可出现,可返回值、列、表
返回
值:比较(>, <, =, <>…)
列:in
all 和 any
在子查询前加入all 或 any ,按字面义理解,对比所有或某个值
exists
是否存在记录,只要有符合子查询的记录,就返回
每行都查询一遍
有 exists 的查询语句是外层查询每一行丢给子查询,如果有记录则保留该行,没有则不返回

集合查询

在两个查询间进行计算

数据修改

插入数据

修改数据

删除数据

update 或 delete 如果没有 where 约束,则会将表中所有行覆写

视图

一般不保存数据,且不一定能更新
能否更新在于数据库能不能唯一定位到底要改原表的哪一行、哪一列
  • 有聚合函数或 group by 的视图不能更新
  • 有 distinct 的基本不能更新,因为不能确定是原表的那个;即使原表中仅有一个,一般也仍然会被判定为不可更新
  • 有多表连接的一般不可更新

创建视图

或者带重命名版本
原列
视图列
sid
id
name
student_name
age
student_age
with check option
只能在仍满足查询条件的情况下进行修改原表
若不带 with check option ,则可以随意修改

删除视图

数据库安全与保护

数据库的安全性

数据库系统的安全概述

  1. 网络系统层次
    1. 负责“用户如何通过网络访问数据库”
  1. 宿主操作系统层次
    1. 提供数据库运行的基础环境(资源管理者(Windows / Linux / Unix))
  1. 数据库管理系统层次
    1. 负责“真正管理数据”的逻辑系统

存取控制

自主访问控制(Discretionary Access Control, DAC)
数据的拥有者决定谁能访问它
可以转让权限
用户自己控制权限
安全性较弱,权限易扩散
强制访问控制(Mandatory Access Control, MAC)
访问权限由系统统一规定,用户不能随便改
低级不能读高级 高级不能把高级数据写进低级
系统控制权限,用户无法修改规则
安全性高
管理成本高
对象权限
授予权限
with grant option :同时将“分发该权限”的权限给予该用户
public :所有用户
all :全部操作权限
收回权限
会同时收回 with grant option

审计

例子:
创建审计策略
启用审计策略
验证审计策略,查询审计信息
禁用审计

数据库的完整性

状态约束
对数据库在某一时刻的数据状态所施加的约束
此刻本表中的数据必须都是合法的
变迁约束
对数据库状态变化过程的约束(允许什么操作导致什么变化)
不能乱改数据,操作必须合法

完整性约束条件

见 关系型数据库 - 关系的完整性约束

数据库完整性约束

按约束对象

属性级完整性
单一属性自己是否合法
年龄不能为负,不能大于250
元组级完整性
多个字段之间必须满足逻辑关系
开始时间必须早于结束时间
关系级完整性
管“表与表之间”或“全表范围”
primary key唯一性
外键、参照一致性

按检查时机

静态完整性约束
只检查当前数据是否合法
动态完整性约束
约束数据“变化过程”是否合法
扣款这一变动不能大于余额
已支付的订单不能取消

完整性控制

外码是否接受空值

在被参照关系中删除元组

级联删除(Cascaded)
on delete cascade
B表中参考A表的att属性(att为外键),在A表中删除一个att值a,B表中所有外键为a的关系都直接被删除
受限删除(Restricted)
on delete restrict
B表中参考A表的att属性(att为外键),B表中外键为a的关系,则无法删除A表中att为a的关系
置空值删除(Nullified)
on delete set null
B表中参考A表的att属性(att为外键),在A表中删除一个att值a,B表中所有外键为a的关系都变为依赖 NULL (前提是外键字段必须允许为 NULL )

在参照关系中插入元组

没有语句,默认为受限插入,若要进行递归插入则需要先在被参照表中插入值,再在原表中插入
受限插入(Restricted Insert)
外键必须在父表中存在,否则禁止插入
递归插入(Cascaded Insert)
插入子表时,如果父表不存在对应记录,会“自动先插入父表”

修改被参照关系中的被参照属性值

级联修改(Cascaded)
on update cascade
B表中参考A表的att属性(att为外键),在A表中修改一个att值(a→b),B表中所有外键为a的关系都直接被修改为b
受限删除(Restricted)
on update restrict
B表中参考A表的att属性(att为外键),B表中外键为a的关系,则无法修改A表中att为a的关系的att值
置空值删除(Nullified)
on update set null
B表中参考A表的att属性(att为外键),在A表中修改一个att值a,B表中所有外键为a的关系都变为依赖 NULL (前提是外键字段必须允许为 NULL )

数据库并发控制

并发控制概述

事务

数据库的逻辑工作单位
一组要么全部成功,要么全部失败的数据库操作集合
满足ACID
  • 原子性(Atomicity)
    • 全做 OR 全不做
  • 一致性(Consistency)
    • 合法状态 → 另一个合法状态
  • 隔离性(Isolation)
    • 各个事务互不干扰
  • 持久性(Durability)
    • 事务提交 → 永久保存
指令
commit :保存此事务,并开始下一事务
rollback :撤销此事务,回到此事务开始前的状态,开始下一事务

并发操作

事务串行执行
每个时刻执行一个事务
交叉并发方式
  • 多个事务穿插执行
  • 每次只执行一个操作(或一小段)
同时并发方式
多机处理系统中,每个处理及运行一个事务,多个处理机同时运行

数据的不一致性

丢失修改(Lost Update)
两个事务并发执行时,后提交的事务覆盖了先提交事务对数据的修改,导致先前事务的更新结果丢失。
即:后写的人把前写的改没了
时间
T1
T2
t1
读余额100
ㅤ
t2
ㅤ
读余额100
t3
+50 → 150
ㅤ
t4
ㅤ
-30 → 70
t5
写150
ㅤ
t6
ㅤ
写70 ❌
最终读70或150,都不对
脏读(Dirty Read)
指一个事务读取了另一个事务尚未提交的修改数据,而该事务随后可能回滚,导致读取到的数据是无效的。
即:读到了别人中途改的、不确定会不会保留的数据
脏:在草稿纸上没有归档(commit)的数据,有可能rollback
不可重复读(Non-repeatable Read)
在同一事务中,两次读取同一数据,由于其他事务对该数据进行了修改并提交,导致两次读取结果不一致的现象。
即:同一个事务里,两次读取同一条数据,结果不一样
在此事务的两次读取中间,另一事务commit了(修改了这个值),导致两次读的结果不同。
两次都没有脏数据,值确实变了
幻读(Phantom Read)
指在同一事务中,执行范围查询时,由于其他事务插入或删除了满足条件的记录并提交,导致再次查询时结果集中出现新增或消失记录的现象。
即:同一个事务中,两次执行“范围查询”,结果集多了或少了“新行”
不是数据被改,而是统一范围内出现了新纪录或少了记录
具体差别
脏读 🆚 不可重复读
脏读:读到的数据可能是“错的”
不可重复读:统一数据独到的两个值不同,但都是对的
幻读 🆚 不可重复读
幻读:范围内的数据条数/行数变化
不可重复读:某一属性值变化

可串行性

可串行性(Serializability)
并发执行的事务,其最终结果等价于某一种“串行执行顺序”
为保证并行操作的正确性,BDMS的并行机制必须提供一定的手段来保证调度是可串行化的。(普遍采用封锁方法)
事务的隔离级别
用来规定多个事务并发执行时“互相能看到什么程度的数据变化”
读未提交(Read Uncommitted)
其他事务没有提交的数据也能看见
读已提交(Read Committed)
只能看见已经提交的数据
可重复读(Repeatable Read)
同一事务中,多次读取同一数据结果一致
可串行化(Serializable)
事务一个一个执行
隔离级别
丢失修改
脏读
不可重复读
幻读
读未提交
❌
✔️
✔️
✔️
读已提交
❌
❌
✔️
✔️
可重复读
❌
❌
❌
✔️(理论)
可串行化
❌
❌
❌
❌

封锁(Locking)

在事务访问数据前,事务对数据加“限制标记”,控制其他事务能不能读或写。
确保事务的隔离性(Isolation)
封锁类型
共享锁(Shared Lock,S锁,读锁)
多个事务可以同时加S锁
只能读,不能写
当一个属性att被一个事务t加S锁时,其他事务只能给att加S锁,直到t释放att上的S锁
排他锁(Exclusive Lock,X锁,写锁)
只有一个事务可以加X锁
被加X锁后,该数据被独占访问
当一个属性att被一个事务t加X锁时,只有t能对att进行读写,其他事务不能给att加任何锁,也不能读写,直到t释放att上的X锁
封锁粒度(Lock Granularity)
数据库中锁定数据对象的大小范围
从大到小:
数据库 > 表 > 页 > 行 > 属性

封锁协议(Locking Protocol)

保证数据 “一致性” 的封锁协议——三级封锁协议
一级封锁协议(Level 1 Locking Protocol)
事务在修改数据之前必须加X锁,直到事务结束(commit 或者 rollback)才释放
如果只读数据,不需要加锁
不能避免:
  • 脏读
  • 不可重复读
  • 幻读
二级封锁协议(Level 2 Locking Protocol)
在一级基础上:读数据前必须加S锁,读完即可释放S锁
不能避免:
  • 不可重复读
  • 幻读
三级封锁协议(Level 3 Locking Protocol)
在二级基础上:事务中所有S锁和X锁都必须在事务结束后才释放
不能避免:
  • 幻读
一级 🆚 二级 🆚 三级
一级:
写数据要X锁,事务结束释放X锁
二级:
写数据要X锁,事务结束释放X锁
读数据要S锁,读完即可释放S锁
三级:
写数据要X锁,事务结束释放X锁
读数据要S锁,事务结束释放S锁
保证并行调度 “可串行性” 的封锁协议——两段封锁协议(Two-Phase Locking,2PL)
事务的加锁和解锁必须分为两个阶段,从而保证并发调度具有可串行性
注意:保证可串行性,而不保证死锁不发生
第一阶段:扩展阶段(Growing Phase,加锁阶段)
事务可以:申请S锁、X锁,获得S锁、X锁
事务不可以:释放任何锁
第二阶段:收缩阶段(Shrinking Phase,解锁阶段)
事务可以:释放已经持有的锁
事务不可以:申请任何新锁
关键点:一旦释放了第一个锁,就不能再申请任何新锁
两个阶段以事务中间第一次释放锁为分界

活锁(Livelock)和死锁(Deadlock)

活锁(Livelock)
系统一直在运行,但某些事务由于不断让步或资源分配不公平,始终无法完成。
解决办法:FIFO
死锁(Deadlock)
两个或多个事务互相等待对方释放锁,导致所有事务都无法继续执行。
解决方法
  • 死锁的预防
      1. 一次封锁法
        1. 事务开始执行前,一次性申请本事务需要的全部锁;只有全部申请成功后,事务才能开始执行。
          如果有任何一个锁申请不到:
          • 不执行事务
          • 不获得任何锁
          • 等待下次重新申请
          缺点:
          • 实际上事务开始前难以预知执行过程中需要访问的全部数据对象,导致要不断扩大封锁范围
          • 锁长期占用,降低并发度
      1. 顺序封锁法
        1. 所有事务必须按照相同的顺序申请锁。
          例如:
          规定所有事务必须按照R1, R2, R3, R4的顺序申请锁
          这样就避免了上述例子中的互相循环等待情况的发生
          缺点:
          • 维护上锁顺序在实际上很难,成本很高
          • 实际上事务开始前难以预知执行过程中需要访问的全部数据对象,可能事务执行到一半发现需要封锁前面的属性
  • 死锁的诊断与解除
    • 诊断
      用事务等待图(有向图),并发控制子系统周期性检测事务等待图,如果图中出现回路,则表示出现死锁。
      解除
      选择一个代价最小的事务作为牺牲者(Victim),撤销(Rollback)该事务,释放其占有的锁。
      • 年轻:完成工作量少
      • 年老:完成工作量多
      一般策略:使年轻的事务先退回去,让年老的事务先执行,年老的事务完成后释放锁,年轻的事务再执行。

数据库恢复技术

故障的种类

事务故障(Transaction Failure)
单个事务自身执行失败
可预期事务故障
应用程序可以发现的故障(undo)
余额不足、年龄为负等
非预期事务故障
应用程序无法处理,由系统处理(rollback)
死锁、溢出、除零等
rollback 和 undo 的区别
rollback是命令,undo是实现。
rollback :终止当前事务,并撤销该事务已经完成的所有修改。
undo:根据 Undo Log(撤销日志),把已经修改的数据恢复成原来的样子。
执行 rollback 时:
系统故障(System Failure)
整个数据库管理系统突然停止运行
内存数据丢失,外存数据正常,所有正在进行的事务中断
停电、OS崩溃、CPU故障
事务A已经提交,但修改还没有写到磁盘;
事务B修改了一半,还没有提交。
系统重新启动后
恢复程序 对未完成的事务:undo
  • 强行撤销所有未完成事务
  • 清除尚未完成事务对数据库的所有修改
恢复程序 对已完成的事务:redo已提交但未持久化的事务
  • 重做已提交但未写入磁盘的事务操作
介质故障
外存故障
火灾、水灾等导致硬盘损坏
装入故障前某时刻的数据库副本,自该时刻所有成功的事务全部重做(redo)
计算机病毒

恢复的实现技术

数据转储(Data Dump / Backup)
静态转储
转储时数据库停止运行,数据完全一致
动态转储
边运行边备份,可能产生数据不一致的问题
需要配合日志文件修复
海量转储
备份全部数据库
增量转储
只备份变化的数据
节省时间空间
登记日志文件
实时记录所有对数据库的更新操作
一般有以下三类记录:
  • 每个事务开始时,登记该事务开始
  • 每个事务结束时,登记该事务结束(commit或rollback)
  • 任何事务的任何一次对数据库的更新都必须在日志中登记一条记录。格式如下
    一个事务的标准日志:
    为保证数据库是可恢复的,日志文件必须遵守以下两个原则:
    1. 等级的次序严格按并行事务执行的时间次序
    1. 必须先写日志文件,后写数据库

    恢复策略

    事务故障的恢复
    事务未正常终止时,利用日志文件undo
    1. 反向扫描日志文件,找到该事务的记录
    1. 找到的若为开始记录,则以undo结束,否则执行该纪录的逆操作,并继续反向扫描
    系统故障的恢复
    1. 从头正向扫描日志文件,直到故障发生时刻(日志结束)
      1. 遇到某事务开始记录,将该事务放入undo队列中,并继续扫描
      2. 遇到一条commit结束的事务记录,则把事务移入redo队列中并继续扫描
      3. 得到undo队列和redo队列
    1. 反向扫描日志文件,遇到undo队列中的事务的记录则执行逆操作
    1. 正向扫描日志文件,遇到redu队列中的事务的记录则重新执行该操作

    检查点技术

    检查点记录内容:
    1. 建立检查点时刻所有正在进行的事务清单
    1. 这些事务最近的一个日志记录的地址
    重新开始文件
    记录各个检查点记录在日志文件中的地址

    关系型数据库设计理论

    数据依赖对关系模式的影响

    例表:
    学号
    学生姓名
    课程号
    课程名称
    教师
    1001
    张三
    C001
    数据库
    王老师
    1002
    李四
    C002
    操作系统
    李老师
    1002
    李四
    C001
    数据库
    王老师
    1003
    王五
    C001
    数据库
    王老师
    插入异常(Insertion Anomaly)
    由于表结构设计不合理,导致某些信息无法单独插入,必须依赖其他无关数据才能插入
    在例表中,学校新开了一门课,课程号、课程名称、教师均已确定,但由于学生还未选课,导致无法插入新课。
    删除异常(Deletion Anomaly)
    删除某条数据时,把本来应该保留的信息也一起删除了
    在例表中,张三退课数据库,删除第一行后,数据库的课程信息被一并删除
    修改异常(Update Anomaly)
    同一信息存放在多个地方,修改时必须修改所有记录,否则数据会不一致。
    数据库换由墨老师教,则1、3、4行均需修改。

    关系模式的规范化

    函数依赖(Functional Dependency,FD)

    如果对于关系 的任意两个元组(Tuple),只要它们在 X 上的值相同,那么它们在 Y 上的值也一定相同,则称:X 函数决定(Determine)Y,或 Y 函数依赖于 X。
    记作:X → Y
    即每一个X能唯一确定Y
    函数依赖需要关系中的所有实例均满足约束条件
    单属性决定
    X → Y
    组合函数依赖
    (X, Y) → Z
    其中X或(X, Y)叫做这个函数依赖的决定属性集或决定因素
    函数依赖具有传递性
    平凡函数依赖
    右侧的属性被全部包含在左侧属性中,不需要推导
    X → X
    (X, Y) → X
    非平凡函数依赖
    右侧的属性不全被包含在左侧属性中,即能推出新的属性
    完全函数依赖(Full Functional Dependency)
    (X, Y, Z) → A
    X, Y, Z中任何一个或几个都不能决定A,必须全部一起才能决定A
    记作:
    部分函数依赖(Partial Functional Dependency)
    (X, Y, Z) → A
    X, Y, Z中任何一个或几个就能决定A
    记作:

    码

    候选码与主码
    若,则B是该关系的候选码
    若候选码多于一个,则选出一个作为主码
    超码(Super Key)
    能够确保唯一性的属性
    该属性应该能唯一确定一行数据
    可以有冗余
    (与候选码的区别)
    超码 = 唯一标识能力 + 任意多余属性(学号+性别、学号+年龄、学号,都是超码)
    候选码是最小超码
    主属性(prime attribute)
    在任意候选码中的属性
    其他属性
    非主属性/非码属性:不在任何候选码中的属性
    单码:单个属性就是码
    全码:整个属性组作为候选码

    范式

    第一范式(1NF,First Normal Form)
    每个属性都是不可再分的原子值(Atomic Value)
    学号
    姓名
    电话
    1001
    张三
    138xxx, 139xxx ❌
    1002
    李四
    136xxx ✔️
    第二范式(2NF,Second Normal Form)
    关系满足1NF,且
    每个非主属性都完全函数依赖于候选键
    即:非主属性必须“完整依赖”主键,不能只靠主键的一部分。
    学号
    课程号
    学生姓名
    课程名称
    成绩
    1001
    C001
    张三
    数据库
    90
    1001
    C002
    张三
    操作系统
    80
    该表中:
    • 候选键:(学号,课程号)
    • 学号 → 学生姓名
    ❌ 所以不满足2NF
    解决办法:
    拆成学生表(学号,姓名),课程表(课程号,课程名),选课表(学号,课程号,成绩)
    判断一个关系是否满足2NF:
    1. 找候选键
    1. 找非主属性
    1. 检查是否存在“部分依赖”
    第三范式(3NF,Third Normal Form)
    关系满足2NF,且
    非主属性不传递依赖于候选键。
    即:非主属性只能“直接依赖主键”,不能“多步传递依赖(A→B, B→C, C传递依赖于A)”
    注:平凡函数依赖不属于传递依赖。
    学号
    姓名
    学院
    学院地址
    1001
    张三
    计算机学院
    A楼
    1002
    李四
    软件学院
    B楼
    该表中:
    学号 → 学院 学院 → 学院地址
    学号 → 学院地址(传递得到)
    ❌ 所以不满足3NF
    解决办法:
    拆成学生表,学院表
    判断一个关系是否满足3NF:
    1. 找候选键
    1. 找出所有函数依赖
    1. 检查是否有传递依赖
    BCNF(Boyce–Codd Normal Form,巴斯-科德范式)
    关系满足3NF,且
    对于每一个非平凡函数依赖 X → Y,X 必须是超码。
    即:关系所有的函数依赖中,在左侧的必须是超码
    学号
    课程
    教师
    1001
    数据库
    王老师
    1002
    数据库
    王老师
    1003
    操作系统
    李老师
    该表中:(一个教师只教一门课,一个学生同一门课只有一个教师。)
    (学号,课程),(学号,教师)是候选码
    • (学号,课程) → 教师
    • 教师 → 课程
    教师不是超码,单独的教师属性不能确定唯一的一行
    ❌ 所以不满足BCNF
    判断一个关系是否满足BCNF:
    1. 找候选键
    1. 找出所有函数依赖
    1. 检查左侧是否有不是超码的属性
    3NF 与 BCNF
    对于每一个非平凡函数依赖 X → Y:
    • 3NF:X 是超码 或 Y 是主属性。
    • BCNF:X 是超码

    多值依赖与第四范式

    多值依赖(Multivalued Dependency,MVD)

    一个属性 X 决定了多个“彼此独立”的属性集合 Y 和 Z。
    即:X对Y, Z的影响互不干扰,相互独立。对于固定 X,Y 的取值集合与其他属性无关,可以自由组合。
    记作:
    学号
    课程
    爱好
    1001
    数据库
    篮球
    1001
    数据库
    音乐
    1001
    操作系统
    篮球
    1001
    操作系统
    音乐
    对同一个学号:
    • 有多个课程
    • 有多个爱好
    但课程和爱好之间是“独立组合”的,不相互决定且可以自由组合 导致出现“课程 × 爱好”的笛卡尔积
    学号 ↠ 课程 学号 ↠ 爱好

    第四范式(4NF,Fourth Normal Form)

    关系满足1NF,且
    对于每一个非平凡多值依赖 X ↠ Y,X 必须是超码
    即:一个决定因素 X 只能决定一组“整体结构”,不能同时决定多个彼此独立的值集合。
    解决了多值依赖问题
    解决上表问题:
    拆表:学生-课程表,学生-爱好表
    消除了“课程 × 爱好”的笛卡尔积
    把“彼此独立的多值属性”拆成不同关系
    判断一个关系是否满足4NF:
    1. 找多值依赖X ↠ Y
    1. X是否为超码
    1. 检查是否有独立多值属性
    上一篇
    “三下乡”
    下一篇
    Linux与shell命令

    评论
    Loading...