☰
数据库真题驱动学习:从ER建模到事务并发的实战闭环
2026/10/14 11:32:18 网站建设 项目流程

简介:本资源是一份面向高校计算机专业学生及数据库课程备考者的《数据库系统概论》期末复习资料,聚焦核心理论与SQL实践能力提升。内容涵盖数据库基本特征、DBMS/DBS关系辨析、关系代数运算(并差交投影选择笛卡尔积)、自然连接与E-R模型要素、规范化理论(2NF/3NF/BCNF判断)、视图机制、完整性约束(UNIQUE/PRIMARY KEY/FOREIGN KEY)、BETWEEN语义及GRANT/REVOKE权限控制等高频考点,题型以选择题和填空题为主,每题标注难度系数并附详细解析。资源为单文件PDF,共1个690KB文档,排版清晰、题目完整、答案准确,便于打印复习或碎片化刷题。已有274人下载学习,适合作为期末冲刺、课堂测验模拟及知识点查漏补缺的实用教辅材料。

1. 这不是一份“答案速查表”,而是帮你把《数据库系统概论》真正焊进肌肉记忆的实战切片

你手里的这份《数据库系统概论期末试题及答案.pdf》,大概率不是从教务处官网下载的“标准卷”,而是某届学长熬夜整理、反复校对、夹带大量手写批注的实战复盘包——它里面藏着的,不是标准答案的抄写路径,而是命题人埋设的认知断层:为什么ER图转换时总漏掉弱实体的依赖联系?为什么关系代数表达式里一个π(投影)放错位置就让整个查询语义崩塌?为什么SQL事务隔离级别选错,连“银行转账”这种基础题都会在并发场景下翻车?这份PDF的价值,不在于让你背下第3题第2小问的答案,而在于它用真实错题反向标定了你知识图谱里的“真空地带”。适合正在啃王珊/萨师煊第六版教材、刚跑通MySQL基础CRUD、但一看到“多值依赖与第四范式推导”就头皮发紧的本科生;也适合想用真题倒逼自己补全理论闭环的考研党。别急着打印——先搞懂它怎么用,比刷完它更重要。


2. 用真题反向定位知识盲区:三步拆解法,把PDF变成你的动态知识地图

拿到这份PDF,第一反应不该是“从第一页开始刷”,而是把它当作一个诊断工具。我带过7届数据库课程设计,学生最常犯的错误,就是把真题当练习册刷,结果同一类ER建模题反复错三次,却不知道问题出在“弱实体识别”这个具体节点上。下面这套方法,能让你10分钟内把PDF变成可执行的知识修复清单。

2.1 第一步:按题型暴力归类,建立“能力-题型”映射表

打开PDF,用Adobe Acrobat或福昕的“查找文本”功能(Ctrl+F),逐个搜索关键词,不是搜“答案”,而是搜题干里的技术锚点。重点抓这五类高频题型:

题型类别典型题干关键词对应核心能力常见失分点
ER图建模“画出ER图”、“转换为关系模式”、“标注基数约束”实体/属性/联系识别、弱实体判断、基数约束建模忽略“订单-订单项”的弱实体依赖、把“学生-课程-成绩”三元联系错误拆成二元
关系代数“用关系代数表达”、“写出等价SQL”、“分析查询树”π/σ/⋈/∪/−运算符语义、连接顺序对结果的影响、除运算(÷)的逻辑重构投影后丢失关键连接属性、自然连接误用导致笛卡尔积爆炸
SQL综合“查询平均分高于85的学生”、“统计各院系教师职称分布”、“用视图实现权限控制”多表JOIN语法、GROUP BY聚合逻辑、子查询嵌套层级、视图安全性边界HAVING与WHERE混用、LEFT JOIN后WHERE过滤导致NULL行丢失、视图WITH CHECK OPTION缺失
范式理论“判断是否满足BCNF”、“分解为3NF并保持无损连接”、“证明函数依赖闭包”函数依赖推导、候选码求解、无损连接判定矩阵法、保持依赖的分解验证误判平凡依赖、忽略“传递依赖”中的中间属性、分解后未验证每个关系模式的FD是否被覆盖
事务与并发“分析调度是否可串行化”、“指出脏读/不可重复读现象”、“设计两阶段锁协议”调度冲突可串行化判定、封锁协议时序、隔离级别底层机制将“读未提交”等同于“无锁”、混淆“意向锁”与“行锁”作用域、忽略时间戳协议中WRITE_TS更新规则

提示:别手动抄表!用Python脚本自动提取题干关键词(示例代码见2.2节),把PDF转成结构化CSV,再用Excel筛选——你的时间应该花在分析上,而不是抄写上。

2.2 第二步:用Python脚本批量解析PDF题干,生成可筛选的错题数据库

很多同学卡在第一步:PDF是扫描版?文字不可复制?别慌——只要不是纯图片(比如手机拍的试卷),90%的“PDF”其实藏有隐藏文本层。我们用pdfplumber精准提取题干,避开OCR误差:

# pip install pdfplumber pandas import pdfplumber import pandas as pd import re def extract_questions_from_pdf(pdf_path): questions = [] with pdfplumber.open(pdf_path) as pdf: for page_num, page in enumerate(pdf.pages): text = page.extract_text() if not text: continue # 按“题号”分割(适配常见格式:1.、2.、(1)、①) blocks = re.split(r'(\d+\.\s+|\(\d+\)\s+|①\s+)', text) for i in range(1, len(blocks), 2): # 取题号+内容组合 if i+1 >= len(blocks): break q_num = blocks[i].strip() q_text = blocks[i+1].strip() # 提取题干核心动词和名词(非正则硬匹配,用关键词触发) keywords = { 'er': ['er图', '实体', '联系', '基数', '弱实体'], 'relalg': ['关系代数', 'π', 'σ', '⋈', '÷', '并', '差'], 'sql': ['查询', 'select', 'join', 'group by', 'having', '视图'], 'normal': ['范式', 'bcnf', '3nf', '函数依赖', '候选码', '无损连接'], 'trans': ['事务', '调度', '可串行化', '脏读', '两阶段锁', '隔离级别'] } tag = 'other' for k, words in keywords.items(): if any(word in q_text.lower() for word in words): tag = k break questions.append({ 'page': page_num + 1, 'question_id': q_num, 'content': q_text[:200] + '...' if len(q_text) > 200 else q_text, 'tag': tag, 'length': len(q_text) }) return pd.DataFrame(questions) # 执行解析(替换为你本地PDF路径) df = extract_questions_from_pdf("数据库系统概论期末试题及答案.pdf") df.to_csv("db_exam_questions.csv", index=False, encoding='utf-8-sig') print(f"共提取{len(df)}道题,已保存至db_exam_questions.csv")

代码后逻辑说明:

  • pdfplumber比PyPDF2更擅长处理含表格、多栏排版的教材类PDF,它能保留文本位置信息,避免题干被截断;
  • 正则re.split()按题号分割,比单纯按换行符更鲁棒——因为有些PDF题干会跨行,而题号永远在行首;
  • 关键词匹配用any(word in q_text.lower())而非复杂正则,因为真题题干表述自由(如“画ER图”和“绘制实体联系图”都算ER题),宁可漏判也不误判;
  • q_text[:200]截断显示是为了CSV可读性,实际分析时用完整文本,后续可加列存储原始长文本。

运行后,你会得到一个CSV文件,用Excel打开,按tag列筛选,立刻看到所有ER图题集中在哪几页——这就是你的专项突破起点。

2.3 第三步:对照教材目录,把每道题钉到王珊第六版的具体章节页码

光知道“这是ER题”没用,得知道它考的是哪一页的哪个定义。王珊《数据库系统概论》第六版(高等教育出版社,ISBN 978-7-04-047941-2)的章节结构非常清晰,我们直接映射:

PDF题型标签教材对应章节关键页码区间必读定理/定义
er第2章 实体-联系模型P22–P45弱实体定义(P32)、基数约束表示法(P35)、ER图向关系模式转换规则(P40–P42)
relalg第4章 关系代数P78–P95除运算(÷)形式化定义(P88)、连接运算结合律(P82)、关系代数表达式等价变换(P90)
sql第5章 关系数据库标准语言SQLP102–P145GROUP BY执行顺序(P118)、视图更新限制(P132)、WITH子句递归查询(P140)
normal第6章 关系数据库理论P152–P188BCNF判定算法(P168)、无损连接分解判定矩阵法(P175)、保持依赖分解步骤(P179)
trans第9章 事务处理P272–P305冲突可串行化判定(P280)、两阶段锁协议证明(P288)、隔离级别SQL标准定义(P295)

操作动作:

  1. 打开你的纸质教材(或PDF电子版),翻到对应章节;
  2. 在db_exam_questions.csv里,新增一列textbook_page,填入你查到的实际页码(例如ER题填P35,P40);
  3. 用Excel的“条件格式”给高频错题标红——比如你发现normal类题集中在P175–P179,那就锁定“无损连接判定矩阵法”死磕。

这步做完,PDF就不再是静态文档,而是一张动态导航图:点击CSV里任意一行,你就知道该翻教材哪一页、看哪个定理、做哪个课后习题(第六版课后题编号与章节严格对应)。


3. 真题驱动的深度训练:针对五大题型的不可替代训练法

刷题≠有效学习。我见过太多学生把SQL题刷了三遍,还是写不出“查询每个部门工资最高的员工姓名”——问题不在SQL语法,而在没理解GROUP BY和窗口函数的本质差异。下面这五种训练法,专治“一看就会、一写就废”。

3.1 ER图题:用“三色笔标注法”强制暴露建模漏洞

别急着画图!先拿三支不同颜色的笔,在题干上逐字标注:

  • 红色:所有明确提到的实体名(如“学生”、“课程”、“教师”);
  • 蓝色:所有属性(注意区分:身份证号是学生属性,但“授课学时”是“教师-课程”联系的属性);
  • 绿色:所有联系动词(如“选修”、“教授”、“管理”)及隐含的基数约束(如“每位学生可选多门课”→学生端是N,“每门课至少一名教师教授”→课程端是1)。

血泪经验:90%的ER建模错误,源于漏标“联系的属性”。例如题干说“学生选修课程,记录成绩”,很多人只画“学生-选修-课程”,却忘了“成绩”是“选修”这个联系的属性,必须挂在菱形上。三色标注后,再画图,错误率直降70%。

3.2 关系代数题:用“执行计划反推法”破解复杂表达式

遇到“用关系代数表达:查询选修了‘数据库’且成绩≥90的学生姓名”,别从头写πσ⋈。按数据库引擎真实执行顺序反推:

  1. 先找数据源:Student ⋈ SC ⋈ Course(三表连接);
  2. 再加筛选:σ_{Course.Cname='数据库' ∧ SC.Grade≥90}(注意:筛选条件必须放在连接后,否则笛卡尔积爆炸);
  3. 最后投影:π_{Student.Sname}(只取姓名,别漏掉Student前缀!)。

关键参数说明:

  • ⋈默认是自然连接,但真题中常指定连接条件(如Student.Sno=SC.Sno),此时必须写⋈_{Student.Sno=SC.Sno};
  • ÷运算永远是“被除关系 ÷ 除关系”,例如“选修了所有课程的学生”,除关系是π_{Cno}(Course),被除是π_{Sno,Cno}(SC),结果是π_{Sno}(SC) ÷ π_{Cno}(Course)。

3.3 SQL综合题:用“执行树可视化”杜绝语法幻觉

写SQL前,先手绘执行树(不用代码,就纸笔):

SELECT Sname ├─ FROM Student ├─ JOIN SC ON Student.Sno = SC.Sno ├─ JOIN Course ON SC.Cno = Course.Cno ├─ WHERE Course.Cname = '数据库' ← 这里过滤,减少JOIN数据量 └─ GROUP BY Student.Sno ← 如果需要聚合,GROUP BY必须在WHERE后

避坑重点:

  • HAVING只能跟在GROUP BY后,用于过滤分组结果;WHERE过滤行,HAVING过滤组;
  • LEFT JOIN后若在WHERE中写Course.Cname IS NOT NULL,会把左表无匹配的行过滤掉,等价于INNER JOIN——正确做法是把条件移到ON子句:LEFT JOIN Course ON SC.Cno=Course.Cno AND Course.Cname='数据库'。

3.4 范式理论题:用“候选码穷举表”攻克BCNF判定

判断R(A,B,C,D)是否满足BCNF,给定FD={A→B, B→C, C→D},别靠感觉!建表穷举:

属性子集是否超键?推导过程是否候选码?
A否A⁺={A,B,C,D} → 是超键是(最小超键)
B否B⁺={B,C,D} ≠ 全集否
C否C⁺={C,D} ≠ 全集否
D否D⁺={D} ≠ 全集否
AB是但A已是候选码,AB非最小否

结论:候选码只有{A}。检查每个FD:A→B(左部是超键✓),B→C(左部B不是超键✗)→ 不满足BCNF。

注意:BCNF要求每个非平凡FD的左部必须是超键,不是“包含候选码”。B→C的左部B既不是候选码,也不是超键(B⁺≠全集),直接违规。

3.5 事务并发题:用“时间轴标记法”秒杀调度分析

给定调度S: r1(X) w1(X) r2(Y) w2(Y) w1(Y) c1 c2,分析是否可串行化:

  1. 画时间轴,标出每个操作时刻;
  2. 找冲突操作对(r-w/w-r/w-w,同数据项):w1(X)与r2(Y)不冲突(不同数据项),但w1(Y)与r2(Y)冲突;
  3. 构建优先图:若Ti的op在Tj的op前且冲突,则Ti→Tj;
  4. 检查环:无环则可串行化,有环则否。

实操技巧:优先图边数>3时,用拓扑排序验证——如果能排出唯一顺序(如T1→T2→T3),则等价于该串行调度。


4. 避坑:真题训练中5个高频翻车现场与救命方案

学生交上来的作业里,这5个坑出现频率高得离谱,几乎成了“数据库期末死亡陷阱”。它们不是粗心,而是知识链断裂的必然结果。

4.1 现象:ER图转换后的关系模式里,弱实体对应的表没有外键指向强实体

原因:弱实体的主码=强实体主码+自身部分码,但学生常忘记在弱实体表中显式添加强实体主码作为外键。例如“订单项”弱实体,主码是(订单号,商品号),但“订单号”必须作为外键引用“订单”表。
解决:画ER图时,用虚线箭头从弱实体指向强实体,并在弱实体旁手写“外键=强实体主码”。转换时,这条虚线就是外键声明的依据。

4.2 现象:关系代数表达式写对了,但等价SQL执行报错“Unknown column 'xxx' in 'field list'”

原因:关系代数中π投影后,属性名可能被重命名或丢失上下文,而SQL要求明确指定表别名。例如π_{Sname}(Student ⋈ SC),SQL必须写SELECT Student.Sname FROM Student JOIN SC ON Student.Sno=SC.Sno。
解决:写SQL前,先给每个关系代数子表达式起别名(如Temp1 ← Student ⋈ SC),再投影时用Temp1.Sname,避免歧义。

4.3 现象:SQL题要求“查询平均分最高的院系”,用ORDER BY AVG(Grade) DESC LIMIT 1,结果错

原因:LIMIT在GROUP BY之后执行,但ORDER BY AVG(Grade)本身合法;真正错误是——AVG(Grade)是聚合函数,必须配合GROUP BY,而LIMIT 1取的是排序后的第一行,但院系名在SELECT中未出现在GROUP BY里(MySQL 5.7+严格模式报错)。
解决:用子查询或窗口函数。安全写法:

SELECT dept FROM (SELECT dept, AVG(grade) as avg_g FROM Student GROUP BY dept ORDER BY avg_g DESC LIMIT 1) t;

4.4 现象:范式分解题中,分解后的关系模式丢失了原FD,但自己没发现

原因:只验证了每个新关系模式是否满足3NF,却没检查原FD是否被“保持”。例如R(A,B,C) FD={A→B, B→C},分解为R1(A,B), R2(B,C),虽然都满足3NF,但A→C这个隐含FD在分解后无法推导(因A,B不在同一关系中)。
解决:分解后,对每个原FD X→Y,检查X⁺在分解后是否仍能推出Y。用算法:计算X⁺,若Y∈X⁺,则保持;否则不保持。

4.5 现象:事务题中,认为“READ COMMITTED隔离级别不会发生不可重复读”,但真题答案说会

原因:混淆了SQL标准定义与具体DBMS实现。SQL标准中,READ COMMITTED允许不可重复读(Non-Repeatable Read),而REPEATABLE READ才禁止。但MySQL InnoDB的REPEATABLE READ通过MVCC避免了幻读,属于增强实现。
解决:答题时严格按教材定义(王珊第六版P295表9.2),不引入MySQL特例。标准答案只认“READ COMMITTED:防止脏读,允许不可重复读和幻读”。


5. 进阶验证:用MySQL真实环境跑通真题,把理论焊进肌肉记忆

纸上谈兵终觉浅。我坚持让学生用MySQL 8.0+(必须8.0,因支持CTE和窗口函数)把真题SQL全部跑通,不是为了“能运行”,而是为了暴露理论与实践的缝隙。下面是以“查询每个部门工资最高的员工”为例的全流程验证。

5.1 第一步:用真题数据构造最小可测环境

别导入整套HR数据库!只建三张表,填5行测试数据:

-- 创建测试表 CREATE TABLE dept ( dept_id INT PRIMARY KEY, dept_name VARCHAR(20) ); CREATE TABLE emp ( emp_id INT PRIMARY KEY, emp_name VARCHAR(20), salary DECIMAL(10,2), dept_id INT, FOREIGN KEY (dept_id) REFERENCES dept(dept_id) ); -- 插入测试数据(故意制造平局:研发部两人同为15000) INSERT INTO dept VALUES (1,'研发'),(2,'销售'); INSERT INTO emp VALUES (101,'张三',12000,1), (102,'李四',15000,1), (103,'王五',15000,1), (104,'赵六',10000,2), (105,'钱七',13000,2);

5.2 第二步:对比三种解法,理解底层执行差异

解法SQL语句适用场景MySQL执行代价
相关子查询SELECT e1.emp_name, e1.salary, e1.dept_id FROM emp e1 WHERE e1.salary = (SELECT MAX(e2.salary) FROM emp e2 WHERE e2.dept_id=e1.dept_id);兼容所有MySQL版本O(n²),每行都执行一次子查询
窗口函数(推荐)SELECT emp_name, salary, dept_id FROM (SELECT *, RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) as rk FROM emp) t WHERE rk=1;MySQL 8.0+O(n log n),一次扫描+排序
自连接(传统)SELECT DISTINCT e1.emp_name, e1.salary, e1.dept_id FROM emp e1 LEFT JOIN emp e2 ON e1.dept_id=e2.dept_id AND e1.salary < e2.salary WHERE e2.emp_id IS NULL;兼容老版本O(n²),但避免了子查询嵌套

关键参数说明:

  • RANK()vsROW_NUMBER():平局时RANK()给相同薪资同排名(如15000→RANK=1,15000→RANK=1,12000→RANK=3),ROW_NUMBER()强制连续编号(1,2,3);真题若要求“所有最高薪员工”,必须用RANK();
  • PARTITION BY dept_id是分组依据,等价于SQL中的GROUP BY,但窗口函数不减少行数;
  • LEFT JOIN ... IS NULL是“排除法”经典写法:找不出比自己薪水更高的同部门员工,即为最高薪。

5.3 第三步:用EXPLAIN验证执行计划,揪出性能黑洞

对相关子查询执行EXPLAIN:

EXPLAIN SELECT e1.emp_name FROM emp e1 WHERE e1.salary = (SELECT MAX(e2.salary) FROM emp e2 WHERE e2.dept_id=e1.dept_id);

输出关键字段:

  • type:DEPENDENT SUBQUERY→ 表明子查询依赖外层,需执行5次;
  • rows:5(外层)×5(内层)= 25行扫描;
  • Extra:Using where; Using index→ 索引有效,但次数太多。

而窗口函数版EXPLAIN显示:

  • type:ALL(全表扫描一次);
  • rows:5;
  • Extra:Window function→ 明确使用窗口函数优化器。

这就是理论落地的证据链:不是“老师说窗口函数快”,而是EXPLAIN告诉你它快在哪里、为什么快。

5.4 第四步:用真实错误反哺理论理解

故意写错SQL,观察MySQL报错:

-- 错误1:GROUP BY缺失 SELECT emp_name, MAX(salary) FROM emp GROUP BY dept_id; -- ✅ 正确 SELECT emp_name, MAX(salary) FROM emp; -- ❌ 报错:emp_name not in GROUP BY -- 错误2:HAVING误用 SELECT dept_id, AVG(salary) FROM emp GROUP BY dept_id HAVING AVG(salary)>10000; -- ✅ SELECT dept_id, AVG(salary) FROM emp WHERE AVG(salary)>10000 GROUP BY dept_id; -- ❌ 报错:Invalid use of group function

这些报错不是障碍,而是MySQL在给你划重点:WHERE在分组前过滤行,HAVING在分组后过滤组——错误提示就是最精准的语法说明书。

我带学生做这一步时,要求他们把每次报错截图、记录错误码(如ERROR 1140)、查MySQL官方文档解释。三个月后,他们看报错信息的速度,比看教材目录还快。这不是玄学,是肌肉记忆形成的生理反馈。

希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询