数据库系统
Last-Modified:2025/6/21
我想在我的笔记里更多地去记录思考,而不是罗列知识。所以这次更新把以前 week1-17的零散笔记折叠起来了。
毕竟大家都是面向考试学习的,这次就在复习完记录一下关于几个考点的思考总结~
为什么要用数据库?
以前操作链表的时候,数据是按序给出的,编程人员可以自行在程序中为数据分配地址。
但是看这道题,数据没有按地址顺序给出,需要对读入的数据按地址进行重组,只是进行一个简单的去重操作,就已经麻烦很多了。
可以发现,问题的根源在于,我们是使用链表,通过物理地址连接的方式将数据关联并存储。
于是,即使不考虑并发,不考虑存储容量瓶颈,不考虑内存管理的复杂性和可维护性。每次数据的布局发生变化的时候,都要重写程序。
于是数据库出现了——1969年数学家Codd发表关系模型
数据之间将通过逻辑建立连接,而不是通过指针、偏移量、磁盘上的内容等这样的物理连接
A Relational Model of Data for Large Shared Data Banks
Week1:数据库简介(Chap 1)、关系模型(Chap 4)
第一章主要回答了我们为什么要用数据库系统这个问题。内容包括相关基础概念和历史。同时也交代了本书的目的:“帮助大家完成范型改变。”,具体地说就是用一种全局的思路去进行“数据库的设计与实现”。
<div class="fold"> <div class="fold-title fold-info collapsed" data-toggle="collapse" href="#collapse-49662e6b" role="button" aria-expanded="false" aria-controls="collapse-49662e6b"> <div class="fold-arrow">▶</div>Q&A </div> <div class="fold-collapse collapse" id="collapse-49662e6b"> <div class="fold-content"> <h3 id="数据库管理系统(DBMS)的发展经历了三代:"><a href="#数据库管理系统(DBMS)的发展经历了三代:" class="headerlink" title="数据库管理系统(DBMS)的发展经历了三代:"></a>数据库管理系统(DBMS)的发展经历了三代:</h3><ol><li><p><strong>第一代 DBMS(层次模型和网络模型)</strong>:</p><ul><li>层次模型:数据以树形结构组织,每个记录类型只有一个父记录类型。</li><li>网络模型:数据以图形结构组织,一个记录类型可以有多个父记录类型。</li><li>优点:结构清晰,易于理解和实现。</li><li>缺点:不够灵活,难以处理复杂的数据关系。</li></ul></li><li><p><strong>第二代 DBMS(关系模型)</strong>:</p><ul><li>关系模型:数据以表格形式组织,每个表格由行和列组成,行表示记录,列表示字段。</li><li>优点:结构简单,易于理解和使用;支持复杂的查询和事务处理。</li><li>缺点:在处理大量数据时性能可能不如其他模型。</li></ul></li><li><p><strong>第三代 DBMS(面向对象模型、对象关系模型等)</strong>:</p><ul><li>面向对象模型:支持对象和类的概念,可以表示复杂的数据结构。</li><li>对象关系模型:结合了关系模型和面向对象模型的优点,支持对象和类的概念,同时保持了关系模型的简单性和易用性。</li><li>优点:支持复杂的数据结构和操作,具有良好的可扩展性和灵活性。</li><li>缺点:实现复杂,需要较高的技术支持。</li></ul></li></ol> </div> </div></div>
关系模型
关系模型定义了一种基于关系的数据库抽象,以避免维护开销。
关键原则:
- 将数据库存储在简单的数据结构(关系)中。
- 物理存储留给数据库管理系统(DBMS)实现。
- 通过高级语言访问数据,DBMS 确定最佳执行策略。 ▶tips
基本概念:数据库——一组数据,数据库管理系统——管理和控制数据的软件,数据库应用——上层程序
也就是说,我们这门课研究的范围不仅包括底层的模型,管理系统,还包括上层的应用程序,与数据库交互的代码。要完全理解DBMS的优缺点,需要从DBMS的发展历史入手。数据库的产生是应生产需求而自然形成的。去更好地理解我们为什么要使用数据库,可以从文件系统开始。这是一个我们每天都在用的东西,我们作为单个用户(只考虑自己对文件的取用),在电脑上创建不同的文件夹归档文件,比如说我将名为“编程”的文件夹中,放入了各种编程涉及到的文档,代码。这对我们目前的需求来说是方便且合理的。为了更快拿到这个数据,我在文件夹下编写小程序,帮我快速读取文件拿到数据。这看起来非常高效了。
但当我们站在一个大公司管理者的角度重新审视这种数据管理方式,就不太高效率了。数据库通过集中管理与分离帮我们解决。
这种考虑方式的转变——范型转换,即本书的目的。从设计思想上,这又是一次面向过程到面向对象的转变,采用更高效的方式解决问题的一种计算机科学思想。以前我们遇到的面向过程编程到面向对象编程,
从原根,阶,同余的讨论到群,环,域的讨论,这都属于我们以前见过的例子。第四章介绍关系型数据库的核心:关系模型。“关系模型最大的优点就在于其逻辑结构简单。但这种简单的结构却有着可靠的理论基础,这正是第一代DBMS所缺乏的。”重点就是要掌握关系数据模型中的概念术语,为后续的设计做好准备。“这里一步错,后边步步错。”关于主关键字和候选关键字的选取是本章一大考点。
<div class="fold"> <div class="fold-title fold-info collapsed" data-toggle="collapse" href="#collapse-4b4a64ee" role="button" aria-expanded="false" aria-controls="collapse-4b4a64ee"> <div class="fold-arrow">▶</div>关系模型涉及的概念 </div> <div class="fold-collapse collapse" id="collapse-4b4a64ee"> <div class="fold-content"> <h3 id="结合关系数据模型,解释下列概念:"><a href="#结合关系数据模型,解释下列概念:" class="headerlink" title="结合关系数据模型,解释下列概念:"></a>结合关系数据模型,解释下列概念:</h3><p>(a) <strong>关系</strong>:在关系数据模型中,关系是指一组元组的集合,每个元组包含相同数量的属性。关系可以被视为一个二维表,其中行代表元组,列代表属性。</p><p>(b) <strong>属性</strong>:属性是关系中的一个列,它代表数据的一个特征或字段。每个属性都有一个名称和一个数据类型,用于描述元组中的特定信息。</p><p>(c) <strong>域</strong>:域是指属性可能取值的集合。例如,如果一个属性是“年龄”,则其域可能是所有非负整数。</p><p>(d) <strong>元组</strong>:元组是关系中的一行,它代表一个实体或记录。每个元组包含一组属性值,这些值对应于关系中的列。</p><p>(e) <strong>内涵和外延</strong>:</p><ul><li><strong>内涵</strong>:指的是概念的本质属性,即定义一个概念所必须具备的特征。</li><li><strong>外延</strong>:指的是概念所包含的具体实例或对象的集合。</li></ul><p>(f) <strong>维和基数</strong>:</p><ul><li><strong>维</strong>:在关系数据库中,维通常指的是一个表中的列数,即属性的数量。</li><li><strong>基数</strong>:基数指的是一个表中的行数,即元组的数量。</li></ul><h3 id="说明数学中的关系与关系数据模型中的关系之间的联系。"><a href="#说明数学中的关系与关系数据模型中的关系之间的联系。" class="headerlink" title="说明数学中的关系与关系数据模型中的关系之间的联系。"></a>说明数学中的关系与关系数据模型中的关系之间的联系。</h3><p>在数学中,关系通常指的是两个集合之间的联系,这种联系可以是一对一、一对多或多对多的。在关系数据模型中,关系被用来表示数据实体之间的联系,这些联系可以通过外键来实现。数学中的关系理论为关系数据库的设计和实现提供了理论基础,特别是在处理多对多关系和规范化方面。关系数据模型中的操作,如选择、投影和连接,都是基于数学中的关系代数理论发展而来的。</p><h3 id="第三代数据库管理系统就是关系型数据库吗?"><a href="#第三代数据库管理系统就是关系型数据库吗?" class="headerlink" title="第三代数据库管理系统就是关系型数据库吗?"></a>第三代数据库管理系统就是关系型数据库吗?</h3><p>第三代数据库管理系统(DBMS)通常指的是面向对象的数据库管理系统(OODBMS)。面向对象数据库尝试将面向对象编程的概念,如继承、封装和多态性,融入到数据库管理系统中。这种数据库管理系统试图更自然地映射现实世界中的对象和它们之间的关系。<br>非关系型数据库(NoSQL),又称为非结构化数据库,是与关系型数据库相对的一个概念。非关系型数据库包括多种类型,如键值存储、文档存储、列族存储和图数据库等,它们通常用于处理大规模数据集,提供高可用性和灵活性。<br>虽然面向对象数据库和非关系型数据库都属于第三代数据库管理系统的范畴,但它们并不是同一个概念。面向对象数据库侧重于将面向对象的概念应用于数据库,而非关系型数据库则侧重于提供不同于传统关系型数据库的存储和查询方式,以适应不同的应用场景和数据模型需求。<br>总的来说,第三代数据库管理系统包括面向对象数据库和非关系型数据库等多种类型,它们各自有着不同的目标和特点。</p> </div> </div></div>
超关键字是一个属性或者属性集合,它能够唯一地标识出关系中的每个元组,候选关键字是最小的超关键字。主关键字是选出作为各元组标识的某个候选关键字。一个关系通常都必须有一个主关键字。外部关键字是一个关系中与另一个关系的候选关键字匹配的属性或属性集合。
空代表对一个元组当前取值还不知道或是不可用的属性值。
实体完整性是一种约束,它规定在基本关系中,构成主关键字的属性的值不能为空。引用完整性规定,一个外部关键字的值或者与主关系的某个元组的候选关键字的值相同,或者为空。除了关系完整性,完整性约束还包括要求必须有值、域和多样性约束,其他完整性约束称为一般性约束。
关系的性质:
- 同一关系模式中各关系模式不能重名(表名不重合)
- 每一个单元格必须确切包含一个原子值(不能空)。
- 不存在重复元组(数据不雷同)。
- 每个属性都有不同的名字(列名不重合)
- 同一属性中的各个值都取自相同的域(对于表中的某一列,该列中的所有数据值都必须属于相同的数据类型,并且遵循相同的约束条件。)
- 属性的顺序不重要
注意:以上是关系的性质,但实际的数据库管理软件不一定严格遵守关系模型。
关系是一个无序集合(unordered set),其中包含代表实体的属性之间的关系。
Week2:ER建模
结构化约束的处理方法:
一对一(1:1)联系
多对多(:)联系
多重性的确定与表示……
关注ER模型建立时可能产生的问题:连接陷阱
两类主要的叫做:扇形陷阱和断层陷阱
Summary:
前边学到,关系模型是一种有效的信息组织方式,并且有着可靠的理论基础。
现在,我们已经确定,我们要以这样的信息组织方式来设计数据库。那么更具体地,如何得到具体的模型?
秉持“会用才是硬道理”的理念,课程进度跳到了Chap12-ER建模,
为了得到这个具体的模型,我们学习ER建模,这是一种建模技术,另一种是规范化的技术在Chap14,15,我们课程将其略过。
得到了具体模型后,为了将其直接设计实施,课程进入Chap16-19:概念数据库设计,逻辑数据库设计,物理数据库设计。
这里书上的说法叫“方法学”——规定了设计过程每一步需要做的事。我们的课程将这个过程融入DreamHouse的实例讲解中,进行实操演示。
Week3: EER建模-概念数据库模型设计
这节课讲解了具体建出来的ER模型,重点是EER建模中子类,超类,泛化……这种概念与处理方法。
Week4: 逻辑数据库模型设计=>物理数据库模型设计
这节课主要讲解了从CDM到LDM发生的变化和需要手动修改的点,以及其原因。
Week5:
Week6:
Week7:
Week8:
Week10:
经历了不知道几周的学习,PowerDesigner的学习进度终于连上了数据库。这周又开始考试了。
开始磨枪了。
第13章:ER=>EER
将超类和子类的概念引入ER模型主要有两个原因。
- 为了避免对相似的概念进行重复的描述
- 为数据库系统设计添加了更多的语义信息
特殊化
通过表示实体成员间的差异特征而将这些成员间的差异最大化的过程。
泛化
通过标识实体成员间的共同特征而将这些成员间的差异最小化的过程。
对于规范化/特殊化来说,有参与约束和不相交约束。
第14章:第一范式(1 NF)
非范式(UNF):包含一个或多个重复组的表
第一范式(1NF):属于第一范式的关系,其每一行和每一列相交的位置有且仅有一个值。
第二范式(2 NF)
完全函数依赖:决定方案应该具有最少的属性,这些属性是保证右边的属性函数依赖于它所必不可少的。
2NF基于完全函数依赖概念,适用于具有合成关键字的关系,即主关键字由两个或两个以上的属性构成。
主关键字仅包含一个属性的关系已经至少是2NF的。
满足第一范式的要求并且要求每个非主关键字属性都完全函数依赖于主关键字的关系。
第三范式(3 NF)
满足第一范式和第二范式的要求并且所有非主关键字属性都不传递依赖于主关键字的关系。
第15章:进一步规范化
BCNF,4NF,5NF
当且仅当每一个函数依赖的决定放都是候选关键字时,某一关系才是BCNF的。
期末复习
关于SQL语句部分,嵌套子查询非常常见。另一个就是————
网安学院最最最最最最爱考的一个SQL语句:双重否定求所有
比如说19-20年的这个最后一问:
关键点:
- NOT EXISTS语句的含义: 检查子查询结果是否为空,若为空则返回真,表示”不存在满足条件的记录”。
- SQL基于集合操作,但是它原生只支持存在量词-
EXISTS
,但不支持全称量词(“所有”)
换句话说,现在我们只有逻辑语句∃,但我们要通过技巧实现逻辑语句∀
SQL中的”所有”逻辑:双重否定NOT EXISTS及其他模式详解
在SQL中表达”所有”或”完全包含”这类逻辑是一个常见但容易混淆的问题。双重否定NOT EXISTS
是解决这类问题的标准模式,下面我将详细解释这种模式及其变体。
一、为什么需要双重否定?
SQL本质上是一个基于集合操作的声明式语言,它原生支持存在量词(EXISTS
),但不直接支持全称量词(“所有”)。因此我们需要通过逻辑转换来表达”所有”的概念。
德摩根定律告诉我们:
1 |
|
即:”对于所有x满足P(x)”等价于”不存在x不满足P(x)”
二、双重否定NOT EXISTS的标准模式
基本结构:
1 |
|
实际案例解析
案例1:找出选修了学号2019123456所有课程的学生
1 |
|
执行逻辑:
- 外层
NOT EXISTS
确保”不存在这样的课程” - 内层
NOT EXISTS
检查”当前学生没选这门课” - 组合起来就是”不存在2019123456选了但当前学生没选的课程”
三、其他实现”所有”逻辑的模式
1. 使用GROUP BY和HAVING计数
1 |
|
适用场景:
- 当可以确保没有重复记录时
- 查询性能通常较好
2. 使用EXCEPT(差集)操作
1 |
|
注意:
- 不是所有数据库都支持EXCEPT
- MySQL中使用
NOT IN
或LEFT JOIN...IS NULL
模拟
3. 使用LEFT JOIN检查NULL
1 |
|
四、类似的高级查询模式
1. “恰好”逻辑(不多不少)
找出选修恰好和2019123456相同课程的学生:
1 |
|
2. “至少N个”逻辑
找出选修了至少3门和2019123456相同课程的学生:
1 |
|
3. “大多数”逻辑
找出选修了超过一半2019123456所修课程的学生:
1 |
|
五、性能考虑
双重NOT EXISTS:
- 逻辑清晰但可能导致性能问题
- 适合基础表有索引的情况
COUNT方法:
- 通常性能较好
- 需要确保计数准确性
EXCEPT方法:
- 语法简洁
- 但并非所有数据库支持
在实际应用中,应根据数据量、索引情况和数据库特性选择最合适的实现方式。
🔍 可恢复性 vs. 级联回滚判断的精细区别
🧩 核心区别总结
特性 | 可恢复性 (Recoverability) | 级联回滚 (Cascading Aborts) |
---|---|---|
关注点 | 事务提交顺序的合理性 | 事务回滚的传播风险 |
判断焦点 | 写入事务和读取事务的提交顺序 | 读取操作是否访问了未提交数据 |
触发条件 | 读后写依赖的提交顺序错误 | 存在读取未提交数据的行为 |
问题本质 | 数据有效性保证 | 回滚范围控制 |
数学表达 | Wᵢ(X)→Rⱼ(X) ⇒ commitᵢ < commitⱼ | ∃ Rⱼ(X) 在 commitᵢ 前且 Wᵢ(X) 存在 |
🧠 深度解析区别(带经典案例)
1. 关注点不同
graph LR
A[可恢复性] -->|确保| B[已提交数据有效]
C[级联回滚] -->|避免| D[单个失败引发连锁回滚]
2. 判断逻辑差异
可恢复性检查:
1 |
|
级联回滚检查:
1 |
|
📚 经典案例对比分析
案例 1: 可恢复但存在级联回滚
1 |
|
- ✅ 可恢复:T1 在 T2 提交前提交
- ❌ 级联回滚:T2 读取了未提交数据(若 T1 回滚会引发级联回滚)
案例 2: 不可恢复但无级联回滚
1 |
|
- ❌ 不可恢复:T2 提交后 T1 回滚,数据失效
- ✅ 无级联回滚:因 T2 已提交,无需回滚(但数据已损坏)
案例 3: 完美调度
1 |
|
- ✅ 可恢复
- ✅ 避免级联回滚
🔍 考试判断技巧矩阵
场景 | 可恢复性 | 级联回滚 | 解释 |
---|---|---|---|
读取已提交数据 | ✅ | ✅ | 理想情况 |
读取未提交数据但写入事务先提交 | ✅ | ❌ | 可恢复但存在级联风险(案例1) |
读取未提交数据且写入事务后回滚 | ❌ | ✅/❌ | 不可恢复,是否级联取决于读取事务状态(案例2) |
无数据依赖 | ✅ | ✅ | 独立事务 |
🚨 关键区别总结
可恢复性是级联回滚的必要非充分条件:
- 避免级联回滚 ⇒ 一定可恢复
- 可恢复 ⇏ 避免级联回滚
时间窗口差异:
- 可恢复性关注 提交时间点
- 级联回滚关注 读取发生时数据状态
问题严重性:
- 不可恢复 = 数据永久损坏 💥
- 级联回滚 = 性能问题(可修复) ⚠️
考试口诀:
“提交顺序保恢复,未提交读引级联”
即:检查提交顺序判断可恢复性,检查是否读取未提交数据判断级联回滚风险
视图可串行化(View Serializability) vs. 冲突可串行化(Conflict Serializability)
1. 定义与核心区别
特性 | 冲突可串行化 | 视图可串行化 |
---|---|---|
判断依据 | 通过交换非冲突操作能否转换为串行调度 | 通过保证所有事务的”读-读”、”读-写”、”写-写”视图与某个串行调度一致 |
严格程度 | 更严格(是视图可串行化的子集) | 更宽松(包含冲突可串行化和部分非冲突可串行化调度) |
实现复杂度 | 容易(通过优先图检测环) | 困难(需要检查所有可能的视图等价) |
实际应用 | 数据库系统普遍支持(如通过两阶段锁实现) | 理论性强,实际系统较少直接支持 |
2. 关键差异解释
(1) 冲突可串行化
- 核心规则:仅允许交换非冲突操作(两个操作来自不同事务、访问不同数据项,或均为读操作)。
- 示例:
1
2
3Schedule:
T1: R(X), W(X)
T2: R(X), W(X)- 冲突操作:
T1.W(X)
和T2.R(X)
不能交换 → 非冲突可串行化。
- 冲突操作:
(2) 视图可串行化
- 核心规则:允许通过盲写(Blind Write)等操作实现视图等价。
- 示例:
1
2
3
4Schedule:
T1: W(X)
T2: W(X)
T3: R(X)- 虽然
T1
和T2
的W(X)
冲突,但若T1
的写被T2
覆盖且T3
只读T2
的结果,则视图等价于串行调度T2 → T1 → T3
(尽管冲突不可串行化)。
- 虽然
3. 数学表达对比
冲突可串行化:
( \text{Schedule} \approx_{\text{conflict}} \text{Serial Schedule} )视图可串行化:
( \text{Schedule} \approx_{\text{view}} \text{Serial Schedule} )
需满足:- 每个读操作读取的值与某串行调度相同
- 最终写入每个数据项的事务与串行调度相同
4. 实际意义
- 冲突可串行化是数据库系统的实际标准(如MySQL/PostgreSQL的可串行化隔离级别基于冲突检测)。
- 视图可串行化主要用于理论分析,揭示哪些调度虽不满足冲突可串行化但仍能保持一致性。
5. 经典反例
盲写(Blind Write)导致的视图可串行化但非冲突可串行化
1 |
|
- 视图等价:等价于串行调度
T2 → T1 → T3
(T3读取T2的结果)。 - 冲突不可串行化:因
T1.W(X)
和T2.W(X)
冲突且无法交换顺序。
总结
- 冲突可串行化 ⊂ 视图可串行化
- 选择依据:
- 需要高并发控制 → 选择冲突可串行化(易实现)
- 需要理论完备性 → 考虑视图可串行化(更通用)
考试中优先检查冲突可串行化(通过优先图),若失败再考虑视图可串行化(需构造视图等价证明)。