恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
数据库系统复习指南:关系代数、SQL与范式全攻略
首页
资讯中心
/
数据库系统复习指南:关系代数、SQL与范式全攻略
数据库系统复习指南:关系代数、SQL与范式全攻略
发布时间:2026/9/16 6:37:18
先说个背景我在西电计科待了四年数据库系统这门课算是本科阶段少数几门“理论听着不难、考起试来见真章”的硬课。考前那段时间我把教材、PPT、历年题来回过了好几遍整理出一套自己的复习笔记最后成绩还算理想。这份笔记我后来也分享给过几届学弟学妹反馈都挺有用。今天把核心内容重新梳理一遍重点放在“考试怎么考、我们该怎么答”上教材以王珊《数据库系统概论》为参照西电的课程体系基本也是沿着这本书走的。这篇内容适合正在备考数据库系统期末的本科生也适合想快速捡起数据库核心概念、准备面试或考研复习的人。我不会从头到尾复述教材而是把高频考点、容易踩坑的地方、以及我自己总结的答题套路全部摊开来讲。你把它当复习提纲也好当考前冲刺资料也好关键是看完之后自己能动手推一遍而不是光“看会了”。1. 复习思路与整体框架1.1 先搞清楚这门课到底在考什么很多同学一上来就背概念背了一个星期发现背了后面忘前面问题就出在没建立知识框架。数据库系统这门课表面上是讲“数据库怎么用”实际上是围绕一条主线展开的数据怎么描述、怎么存储、怎么操作、怎么保证不出错。整门课就是这条主线的四个环节。对应到教材章节大致可以分成四块。第一块是数据描述对应关系模型、关系代数、关系完整性这是全书的地基第二块是数据操作对应SQL语言考试中占比最大也是实际工作中最常用的能力第三块是数据设计对应ER模型、范式理论、模式分解属于“拿到业务需求怎么建表”的方法论第四块是数据保障对应事务、并发控制、数据库恢复这是数据库系统区别于文件系统的核心价值所在。把这四块理顺之后复习顺序也就清楚了。先花两天把关系代数和SQL吃透这是拿分的基础再花两到三天攻克范式理论这是计算推导题的重灾区最后留两天左右搞定事务并发和恢复机制。这样安排的好处是即使时间不够放弃的也只能是最后面的部分前面的核心分已经稳稳拿到。1.2 教材版本与复习资料怎么选教材用王珊《数据库系统概论》第6版是比较主流的选择。第6版和第5版的核心章节差别不大主要是增加了少量新内容比如大数据、NoSQL的简介但这些在期末考试中一般不会深挖。如果你手上是第5版完全没必要再买一本第6版重点章节一模一样。复习资料方面PPT是比教材更重要的素材。老师的PPT往往浓缩了每节课的重点有些题目就是从PPT上的例题变形来的。历年真题更是稀缺资源一定要找到至少最近三年的卷子不是为了押题而是为了摸清老师的出题风格和答题要求。比如有的老师喜欢考“画ER图”有的老师喜欢考“判断范式级别并分解”这两种风格的备考重点是有差别的。还有一个容易忽略的资料是课后习题。王珊教材每章后面的习题质量很高尤其是第3章SQL和第6章关系数据理论很多期末题就是课后题的变体。我当时是把课后题做了两遍第二遍只做错题和重点题效率比盲目刷题高很多。1.3 计算题和概念题的复习比重从我看到的历年考卷和周围同学的反馈来看期末考试的题型通常包括选择题或填空题、简答题、计算/设计题三大类。选择填空考的是基本概念和细节记忆简答题考的是原理阐述计算设计题考的是动手能力。三者的大致分值比例是3:3:4也就是说计算设计题占比最高复习时需要重点倾斜。什么是计算设计题包括但不限于给定关系模式判断范式级别、关系模式分解、关系代数表达式书写、SQL语句编写、ER图设计、判断并发调度是否正确、判断是否发生死锁。这些题目的共同特点是有固定的分析套路只要平时练过考场上就是“肌肉记忆”。所以我建议复习时把重心放在这些题型上概念题靠考前突击背诵就够了。另外要特别提醒一点数据库这门课的计算题很少涉及复杂数值计算更多的是逻辑推导和规则判断。比如范式判断核心是分析函数依赖比如并发调度核心是判断冲突操作对。不要因为看到“计算”两个字就觉得要准备计算器实际上这门课考的是严谨的逻辑思维。2. 关系模型与关系代数全书地基2.1 关系模型的基本概念和完整性约束关系模型的核心思想一句话就能概括用二维表来表示实体和实体之间的联系。这张二维表在理论上就叫“关系”表中的一行叫“元组”表中的一列叫“属性”。听着简单但考试时会在细节上做文章。比如“关系的每个分量必须是不可分的数据项”这一点就是第一范式的基本要求很多同学判断范式时容易忽略。完整性约束是关系模型里绕不开的考点三种完整性必须烂熟于心。实体完整性要求主属性不能取空值因为主键的作用就是唯一标识一条记录主键为空意味着这条记录无法被识别参照完整性要求外键要么为空要么等于被参照关系中某个元组的主键值这是保证表间引用的有效性用户定义完整性则是根据实际业务规则自定义的约束比如年龄必须大于0、成绩在0到100之间。考试的时候这三种完整性经常结合SQL语句来考比如让你在CREATE TABLE语句中写出PRIMARY KEY、FOREIGN KEY、CHECK约束。这里有个细节很多人会漏实体完整性除了主键不能为空还包含主键必须唯一参照完整性除了定义外键还要注意被参照表的主键必须先存在。答题时把这两层含义都写全才能拿满分。2.2 关系代数各运算的考察形式与解题套路关系代数是很多人的痛点因为公式多、符号杂。但如果按“运算对行还是对列操作”来分类其实很好记。对行操作的包括选择σ和连接⋈对列操作的包括投影π还有既对行又对列的集合运算∪、∩、−和笛卡尔积×。除运算÷比较特殊但考试出现的频率不高如果出现往往是直接套定义。选择题经常考的是各种运算的组合辨析。比如“选出年龄大于20的学生姓名”对应的关系代数表达式是π_姓名(σ_年龄20(学生))。注意顺序很重要一定是先做选择再做投影如果先投影年龄属性就被去掉了后面就无法做比较。这种“先选后投”的顺序规律在计算题中经常用到我把这叫作“关系代数的基本操作顺序”。连接运算里有几个概念特别容易混淆等值连接是取两个关系中属性值相等的元组拼接自然连接是等值连接的一种特殊情况要求比较的属性列名称相同并且在结果中去掉重复列外连接则会保留不匹配的元组用空值填充缺失部分。考试常考“自然连接与等值连接的区别”答题要点就是自然连接要求同名属性等值且去重复列等值连接只需指定某属性值相等保留所有列。2.3 关系代数综合题的实战推演我这里给出一道典型题目你可以自己先做一遍再看答案。题目有两个关系学生学号姓名系别年龄选课学号课程号成绩。要求用关系代数表达式查询“选了课程号为‘C1’的学生姓名”。做题步骤是这样先找出选了C1课程的学生学号再根据学号去学生表中找姓名。表达式可以写成π_姓名(σ_课程号‘C1’(学生⋈选课))。这里的核心是先做自然连接把两张表通过学号关联起来再用选择运算筛选出课程号为C1的记录最后投影出姓名列。这个例子看起来简单但已经包含了关系代数题的完整套路读懂需求、确定需要哪几张表、决定连接条件、确定选择和投影的顺序。如果题目再多几个条件比如“查选修了‘数据库’课程的男学生姓名”那就多一步先在课程表中找到数据库对应的课程号再和学生、选课表做连接。难度提升的本质是连接的表变多了但分析思路一模一样。复习关系代数时不要只看不写。我建议把教材上所有关系代数的例子都用纸笔做一遍做完对照答案检查。这个过程最能暴露你对连接条件、投影属性这些细节的理解程度。3. SQL性价比最高的拿分板块3.1 SQL语句的层次拆解与必背语法SQL是期末考试里分值最大、也是最容易突击的部分。它分三个层次数据定义语言DDL负责建表、删表、修改表结构数据操纵语言DML负责增删改查数据控制语言DCL负责权限管理。期末复习的重点放在前两个层次DCL简单了解即可。建表语句是很多SQL大题的第一小问必须写得标准。完整语法包含表名、各列定义、主键约束、外键约束和CHECK约束。我平时写CREATE TABLE的习惯是先列出所有列名和数据类型再单独提约束部分这样结构清晰阅卷老师一目了然。比如CREATE TABLE Student ( Sno CHAR(9) PRIMARY KEY, Sname CHAR(20) NOT NULL, Ssex CHAR(2) CHECK (Ssex IN (男, 女)), Sage SMALLINT, Sdept CHAR(20) );这里有几个细节需要特别注意。CHAR和VARCHAR的区别、NOT NULL约束、CHECK约束的写法都是常考的知识点。另外要注意SQL语句以分号结尾列定义之间用逗号分隔最后一列后面不要加逗号。这些细节看着不起眼但真考场上写错一个逗号可能整道题丢分非常可惜。3.2 聚合函数与GROUP BY的使用禁区聚合函数COUNT、SUM、AVG、MAX、MIN是SQL查询题的核心考点但单独考函数本身不难难点在于和GROUP BY、HAVING的组合使用。做题时记住一个原则只要出现“每个”“各组”这类字眼就大概率需要用到GROUP BY分组之后的条件筛选必须用HAVING而不能用WHERE。我见过最多的错误是搞不清WHERE和HAVING的分工。WHERE是在分组之前对原始记录进行筛选HAVING是在分组之后对组进行筛选。举例来说“查平均成绩大于90分的系”这个需求筛选条件是“系的平均成绩”这个值得先分组计算才能得到所以必须用HAVING而“查年龄大于20岁的学生人数”筛选条件针对的是单条学生记录在分组前就能判断用WHERE就行。另外一个高频错误是SELECT子句中混用聚合函数和普通列。标准SQL规定如果SELECT中出现了聚合函数那么其他非聚合列必须出现在GROUP BY子句中。比如下面这条SQL就是错误的SELECT Sdept, COUNT(*) FROM Student;因为这里的Sdept没有出现在GROUP BY子句中数据库不知道要按哪个系来计数或者显示哪个系。正确写法是SELECT Sdept, COUNT(*) FROM Student GROUP BY Sdept;3.3 连接查询与嵌套子查询的对比选择查询题里经常出现“同一件事可以用连接查询做也可以用嵌套子查询做”的情况。比如“查选了‘数据库’课程的学生姓名”既可以用连接查询把三张表连起来也可以先查出课程号再根据课程号查学号最后根据学号查姓名也就是三层嵌套。连接查询的优点是逻辑直观、执行效率通常更高缺点是语句较长表多了之后容易写乱。嵌套子查询的优点是层次分明每个子查询解决一个问题缺点是有些场景效率偏低代码可读性差。期末考试中两种写法都给分但我的建议是能写连接查询的尽量写连接查询因为阅卷时更容易看出你的思路对不对如果题目明确要求用嵌套查询那必须按题目要求来。关于嵌套子查询的分类重点掌握IN、EXISTS、ANY、ALL这几个关键词的用法。IN和EXISTS都能表达“属于某个集合”但EXISTS在子查询中常和关联子查询配合使用比如“查没有选修任何课程的学生”用NOT EXISTS配合关联子查询就能写出来。ANY和ALL一般和比较运算符连用比如“查年龄大于所有男生年龄的女学生”可以用Sage ALL(男生年龄)来实现。3.4 视图的作用与可更新条件视图是SQL部分常被忽略但容易考到的点。视图的本质是一个虚拟表它的定义不实际存储数据只是保存了一条SELECT语句。每次查询视图时数据库会先执行视图定义中的SELECT语句再对外层查询进行处理。这种机制的好处是逻辑独立性、安全性、简洁性。视图相关的简答题经常问“视图和基本表的区别”或“为什么说视图能够提供一定程度的逻辑独立性”。答题时抓住三个关键词虚拟表、不占存储、动态生成。另外还要能说出视图的优点简化用户操作、提供多角度观察同一数据、安全性高。视图能否更新是个高频考点。一般认为行列子集视图也就是从单个基本表导出、只去掉了部分行和列是可以更新的涉及多个表连接、使用了聚合函数或GROUP BY的视图通常不可更新。因为对多表连接视图的更新数据库无法确定应该修改哪张基本表。记住这个判断原则选择题基本就能拿分。4. 范式理论最容易丢分的计算推导题4.1 函数依赖与候选键的判断方法范式理论的开端是函数依赖。函数依赖描述的是属性间的一种决定关系如果知道X的值就能唯一确定Y的值就称X决定Y记作X→Y。生活中最简单的例子知道学号就能确定姓名所以学号→姓名。判断函数依赖时要特别注意“唯一确定”几个字同样的学号不可能对应两个姓名这才叫函数依赖。候选键的判断是范式题的第一步也是最关键的一步。候选键是能唯一标识一个元组的最小属性集合。找候选键的常用方法是先看哪些属性出现在所有函数依赖的左边或者不出现在任何依赖的右边这些属性大概率是候选键的一部分然后逐步尝试加入其他属性看能否推出全部属性。我总结的解题步骤是这样的第一步找出所有只出现在函数依赖左边、从未出现在右边的属性把这些属性记为集合A第二步计算A的闭包如果A的闭包等于全属性集RA就是唯一的候选键第三步如果A的闭包不等于R就依次尝试向A中加入一个属性或属性组合再计算闭包直到闭包等于R。这样就能找出全部候选键。记住候选键是“能推出全部属性的最小集合”这个定义是判断的终极依据。4.2 1NF到BCNF的递进关系范式的级别是层层递进的理解每一级范式的限制就能理清它们的关系。第一范式1NF要求关系中的每个分量都是不可分的原子值这是表结构的基本要求第二范式2NF在1NF基础上要求消除非主属性对候选键的部分函数依赖第三范式3NF在2NF基础上要求消除非主属性对候选键的传递函数依赖BCNF在3NF基础上更进一步要求消除主属性对候选键的部分和传递函数依赖。这话听起来有点绕。用大白话解释2NF解决的是“候选键由多个属性组成时某些非主属性只依赖于其中一部分”的问题3NF解决的是“非主属性不直接依赖候选键而是依赖另一个非主属性”的传递问题BCNF解决的是“主属性之间也存在不当依赖”的问题。等级越高函数依赖的规范性越强冗余和异常越少。判断范式级别的步骤可以固化下来形成一条流水线第一步找出所有候选键和主属性第二步判断每个非主属性和候选键的依赖关系如果存在部分依赖就不满足2NF第三步如果满足2NF再判断是否存在传递依赖存在则不满足3NF第四步如果满足3NF再检查是否存在主属性对非主属性的依赖有则不满足BCNF。这套流水线做熟练之后一道范式判断题30秒内可以出结果。4.3 模式分解的规则与无损连接判断当关系模式不满足较高范式时解决方案是进行模式分解把一个关系拆成多个关系。分解有两个重要标准无损连接性和保持函数依赖。无损连接指的是分解后再做自然连接能恢复出原始关系不产生额外或丢失的数据保持函数依赖指的是分解后所有函数依赖仍然在某个子模式中成立或者能被推导出来。考试常考“判断某个分解是否具有无损连接性”。最简单的判断方法是看分解后的两个模式的交集是否能决定其中一个模式。具体来说如果关系R分解成R1和R2R1∩R2能决定R1或者R1∩R2能决定R2那么这个分解就是无损的。这里顺便提一嘴如果R1∩R2是R1或R2的超键就满足无损连接条件。判断题里常见的陷阱是“分解保持了函数依赖”和“分解是无损的”不能画等号。有的分解虽然无损但不保持依赖有的保持依赖却是有损的。考试时题目问哪个必须满足一般默认两个都要求满足万一只能选一个优先保证无损连接性因为丢失函数依赖会导致约束无法执行而无损性一旦失去数据就彻底错了。4.4 范式判断的完整练习下面给一道完整练习可以按我之前给的流水线来做。假设关系模式R(A,B,C,D)函数依赖集F{A→B, B→C, C→D}。第一步找候选键。A只在左边出现不在任何依赖右边所以A是候选键的一部分。计算A的闭包A→BB→CC→D所以A的闭包是{A,B,C,D}等于全部属性所以候选键就是A。主属性只有A非主属性是B、C、D。第二步判断2NF。因为候选键只有一个属性A不可能存在对候选键的部分依赖所以满足2NF。第三步判断3NF。B和A之间是直接依赖A→BC依赖于B、B又依赖于A这不是直接依赖于候选键A而是通过B传递得到所以存在传递依赖A→C不满足3NF。结论是R满足2NF不满足3NF。如果要分解到3NF可以根据依赖关系拆成R1(A,B)、R2(B,C)、R3(C,D)。这种分解既保持函数依赖又具有无损连接性。做这类题目的时候一定要把每一步的判断依据写清楚阅卷老师按步骤给分就算最后结论错了中间推导过程也能拿不少分。5. 事务、并发控制与恢复机制5.1 事务四大特性与事务状态的转变事务是数据库中一个不可分割的工作单位要么全部执行要么全部不执行。它的四大特性ACID是简答题的常客原子性强调事务不可分割要么全做要么全不做一致性强调事务执行前后数据库都处于一致状态隔离性强调并发执行的事务之间互不干扰持久性强调事务一旦提交对数据库的改变就是永久的。考试问“数据库如何实现ACID”是进阶考点。原子性靠日志中撤销未完成事务的修改来实现一致性靠原子性和隔离性共同保证隔离性靠并发控制机制锁实现持久性靠数据库把已提交事务的修改写入磁盘日志来保证。这四个实现机制对应到具体的数据库技术就是日志和锁两大体系。理解ACID时可以用一个转账场景A给B转账100元。这个操作包含两个步骤A账户减100B账户加100。如果中间系统崩溃两个步骤必须一起成功或一起失败这就是原子性无论转账前后A和B的余额总和保持不变这是一致性转账过程中其他人不能看到中间状态A已减、B未加这是隔离性转账成功后即使断电重启金额也不能变回去这是持久性。5.2 冲突可串行化调度的分析套路并发控制的目的是让多个事务并发执行的结果等价于它们按某种串行顺序执行的结果。满足这个条件的调度就叫可串行化调度。考试常考“判断两个事务的调度是否冲突可串行化”我的分析套路分三步走。第一步找出所有冲突操作对。冲突操作对的规则是两个不同事务的操作用同一数据项并且至少有一个是写操作。比如T1写A和T2读A就构成冲突对T1读A和T2读A不构成冲突。第二步根据冲突对建立优先关系。如果T1的写A操作排在T2的读A操作之前就记一条边T1→T2。第三步判断优先图是否无环。如果无环调度就是冲突可串行化的如果有环就不是。优先级图的方法也叫有向环检测法。考试时只要画出一个有环图就能直接判定不可串行化。这里有个易错点无冲突的操作对不需要画边比如T1读A、T2读A、T1读B、T2写B这类只有真正发生冲突才需要建立依赖关系。5.3 锁机制与两阶段锁协议锁是数据库实现并发控制最常用的手段。锁的类型要分清共享锁S锁允许事务读数据但不能写排他锁X锁既不允许其他事务读也不允许写。两个事务对同一数据项加锁的规则是可以同时加S锁不能同时加X锁也不能一个S锁一个X锁同时存在。两阶段锁协议2PL保证可串行化的方法值得深入研究。它把事务的加锁和解锁分为两个阶段扩展阶段只能加锁不能解锁收缩阶段只能解锁不能加锁。遵守2PL的调度一定是可串行化的但可能产生死锁因为两个事务可能互相等待对方释放锁。考试常见的题型是给出一个事务序列要求判断它在某个时刻会发生什么状态。比如T1持有A的X锁并请求B的X锁T2持有B的X锁并请求A的X锁这时候两个事务都在等待对方释放资源形成死锁。解决死锁的方法包括超时、死锁检测和死锁预防简答题会要求你列举并简单说明。5.4 日志恢复与检查点机制数据库恢复机制的核心是日志。日志记录了每次事务对数据库的修改包括修改前值用于撤销UNDO和修改后值用于重做REDO。系统崩溃后数据库会根据日志内容决定哪些事务需要撤销、哪些需要重做。判断依据是事务是否已经提交已提交事务的修改可能还没写入磁盘需要重做REDO未提交事务的修改可能已经部分写入磁盘需要撤销UNDO。在日志中已提交事务会有COMMIT记录没有COMMIT记录的事务都必须撤销。检查点CHECKPOINT是恢复机制的优化手段。系统会定期建立检查点此时将内存中的修改写入磁盘并记录日志位置。恢复时只需要从最近一个检查点开始扫描不需要回放整个日志减少恢复时间。简答题考“为什么需要检查点”时答案核心就是“减少恢复时间避免从头扫描全部日志”。6. 考前冲刺与易错点速查6.1 高频题型与答题规范到了考前最后两三天不建议再逐章看教材而是要把精力放在高频题型和答题规范上。数据库试卷中的大题型基本是固定的ER图转关系模式、关系代数表达式、SQL语句编写、范式判断与分解、事务并发调度分析。其中ER图转关系模式这个题型需要单独提醒。它的规则是实体转成关系模式实体的属性就是关系的属性实体的码就是关系的主键1:1联系可以在任意一端添加外键1:n联系可以在n端添加外键m:n联系必须单独转成一个关系模式码由两端实体的主键共同组成。这里面最容易错的是m:n联系的处理很多同学漏掉单独建表这一步直接丢一大半分。答题规范方面我总结了几条经验。关系代数表达式要标明每一步用到的运算符号投影和选择不要写反SQL语句分号别忘了表名、列名写上之后检查一下是否和数据字典一致范式判断要把候选键找出来标注清楚主属性和非主属性再逐个判断是否满足各级范式并发调度分析画优先图时务必标明节点和边的含义有环没有环给出一句结论。6.2 我见过最多的低级失误带过几届学弟学妹复习我发现有些错误几乎是所有人都会犯的这里集中列一下。第一个是把SELECT和投影混淆SQL里SELECT对应的是列的选择WHERE才是行的筛选有人把“查年龄大于20的男生”写成SELECT 年龄 20 FROM Student一看就是没有分清行列操作的层次。第二个是把COUNT()和COUNT(列名)混用。COUNT()统计所有行数包括NULL行COUNT(列名)只统计该列非NULL的行数。题目如果问“有多少学生没有选课”用COUNT(*)会得到错误结果正确做法是对学号列做COUNT并配合NOT EXISTS或LEFT JOIN。第三个是范式题不写候选键直接下结论。没有候选键就无法确定主属性后面的部分依赖、传递依赖判断全都没有依据丢了过程分非常可惜。第四个是事务题没弄清S锁和X锁的兼容矩阵几个锁的关系记混了导致后面的死锁判断全部错误。6.3 考前48小时的复习清单最后48小时我的复习建议是按三天倒排倒数第三天把SQL和关系代数的练习题从头到尾做一遍重点看错题倒数第二天集中攻克范式判断和模式分解每天至少手动推5道题把步骤练成本能倒数第一天背诵简答题要点包括ACID定义、视图作用、三级模式结构、日志恢复原理同时把前面整理的易错点过一遍。之前提到的西电期末题型和网上的“数据库系统”“数据库系统原理”等热词对应的复习资料基本重叠直接按这个清单走就没问题。如果有精力可以把教材课后题中与上面四个板块相关的所有题目再做一遍。尤其是课后题中涉及SQL查询的题目涵盖了大部分常用语法做完一遍基本可以覆盖考试中80%的SQL题型。最后一条关于心态的建议考前不要追求面面俱到把必考的计算设计题练到滚瓜烂熟概念简答题背熟核心要点成绩就不会差。数据库这门课的逻辑链条很完整一旦你弄懂了候选键怎么找、SQL怎么写、事务怎么串行化整门课的知识就像是串在一条线上越到后面复习越轻松。我个人复习时还有一个习惯就是把自己容易错的点用一句话写在便签纸上贴在水杯和电脑旁边。比如“WHERE先于GROUP BYHAVING后于GROUP BY”“COUNT(*)和COUNT(列名)不一样”“判断范式必须先找候选键”这类只有自己能看懂的关键字考前看一遍能有效避免考场上的低级失误。这个方法没什么技术含量但对提分真的很管用你可以试试。