资讯动态

数据库期末考试题怎么复习?从背题到动手复现的完整路径

发布时间:2026/10/9 19:34:54 来源:尧图企业网站定制
简介这份数据库期末考试试题及答案面向高校计算机及相关专业学生用于期末复习、自测与查漏补缺也可供备考数据库原理类课程的读者对照练习。资源以doc文档形式提供压缩包内共1个文件大小约118KB内容为一份完整的期末试卷及配套答案涵盖单项选择题、填空题等题型。试题覆盖数据库系统核心与DBMS、数据模型与概念模型、数据独立性、关系数据模型、E-R模型转换、数据库设计、关系规范化、事务隔离性、封锁协议与数据库恢复等核心知识点并配有标准答案与解析要点便于读者逐题核对、理解易错概念。目前已有3787人学习下载适合需要系统梳理考点、快速检验掌握程度的读者使用。1. 数据库期末考试试题及答案从背题到真懂中间隔着一次动手复现数据库期末考试题绝大多数人拿到手的第一反应是“背”。选择题背选项填空题背关键字简答题背条目大题背SQL模板。背完上考场考完就忘下次遇到同样的查询需求还是写不出来。问题出在试题和答案本身不是知识它们只是知识被压缩后的快照。你背的是快照不是产生快照的那台机器。这个标题真正指向的需求有三层。第一层是应试需要一套结构清晰、覆盖核心考点的题目和参考答案能对着复习。第二层是理解为什么这道题考这个知识点换个条件答案会怎么变。第三层是迁移把试题里的SQL、范式判断、事务分析搬到真实场景里能自己出题、自己验证。这篇文章按这三层来拆重点放在第二层和第三层——因为只做第一层你永远在追下一套题。适合谁看正在准备数据库期末的在校生需要一套可复现的复习路径已经考完但发现自己“只会做题不会用”的开发者想借试题这个壳把底层逻辑补回来以及需要出题或组卷的人想知道一道好题应该卡在哪个点上。2. 试题的四类题型分别卡什么能力先看懂再动手2.1 选择题和填空题考的是边界条件不是定义很多人复习选择题的方式是把答案抄一遍然后反复看。这没用。选择题的真正价值在于每个错误选项都对应一个常见的理解偏差。比如“关系数据库中视图是否可以更新”这类题正确选项往往附带“在特定条件下”这个限定而错误选项就是把条件去掉后的绝对化表述。我一般会这样处理一套选择题先把题干里的关键词圈出来然后在旁边写“这个条件去掉后答案会变成什么”。举个例子-- 题干以下哪个操作会隐式提交事务 -- A. SELECT B. INSERT C. CREATE TABLE D. UPDATE -- 答案C -- 但真正要记的是DDL 语句CREATE/ALTER/DROP/TRUNCATE在多数数据库里会隐式提交 -- 验证方式在事务里执行 CREATE TABLE然后 ROLLBACK看表是否还在逻辑说明这道题表面考“哪个是DDL”实际考的是“事务边界在哪里”。参数说明不同数据库对DDL的处理有差异MySQL的InnoDB引擎下DDL会隐式提交但某些数据库支持事务性DDL。你复习时如果只记“C”换一道“TRUNCATE是否隐式提交”就又不会了。填空题的复习策略类似。填空题的答案通常是一个术语或一个数字但你要问自己这个术语的定义边界是什么这个数字在什么版本、什么配置下成立。比如“第三范式的定义是消除____依赖”答案是“传递函数依赖”。但你要能举出一个反例什么表满足3NF但不满足BCNF。2.2 简答题考的是因果链不是条目列表简答题的参考答案通常是一段话但阅卷时是按点给分。这意味着你背条目就能拿分但拿不到“理解”的分。我的做法是把每个简答题的答案拆成“因为…所以…如果…则…”的因果链。以“为什么需要事务隔离级别”为例参考答案可能写“为了防止脏读、不可重复读、幻读”。但真正的因果链是并发事务互相干扰 → 产生三类异常 → 用锁或MVCC来隔离 → 隔离越强并发越低 → 所以需要分级。你把这个链条写出来简答题的答案自然就有了而且换一道“MVCC如何实现可重复读”也能答。-- 验证不可重复读的最小实验以MySQL为例 -- 会话A START TRANSACTION; SELECT balance FROM account WHERE id 1; -- 假设读到 100 -- 会话B UPDATE account SET balance 200 WHERE id 1; COMMIT; -- 会话A再次查询 SELECT balance FROM account WHERE id 1; -- 在READ COMMITTED下读到200在REPEATABLE READ下仍读到100 COMMIT;逻辑说明这个实验比背“不可重复读的定义”有用得多。参数说明MySQL默认隔离级别是REPEATABLE READ所以会话A第二次读到的还是100。如果你把隔离级别改成READ COMMITTED结果就变了。这个差异就是简答题里“隔离级别影响”的具体体现。2.3 SQL大题考的是查询分解能力不是语法记忆SQL大题是整张试卷里最能拉开差距的部分。常见题型包括多表连接、子查询、聚合与分组、窗口函数、递归查询。很多人卡住不是因为不会写JOIN而是因为读不懂题目的业务逻辑。我的习惯是拿到SQL大题先不写SQL先用自然语言把查询目标拆成三步——要什么数据、从哪些表来、按什么条件过滤和分组。拆完再写SQL写完再用一个小数据集验证。-- 典型题目查询每个部门薪资最高的员工姓名和薪资 -- 第一步要什么 → 员工姓名、薪资、部门 -- 第二步从哪来 → employee 表包含 dept_id, name, salary -- 第三步怎么过滤 → 每个部门内 salary 最大 -- 写法一相关子查询 SELECT e.name, e.salary, e.dept_id FROM employee e WHERE e.salary ( SELECT MAX(salary) FROM employee WHERE dept_id e.dept_id ); -- 写法二窗口函数MySQL 8.0 SELECT name, salary, dept_id FROM ( SELECT name, salary, dept_id, RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rk FROM employee ) t WHERE rk 1;逻辑说明两种写法结果在“薪资无并列”时一致但有并列时相关子查询会返回多行窗口函数用RANK也会返回多行用ROW_NUMBER则只返回一行。参数说明PARTITION BY指定分组列ORDER BY指定排序方向RANK/ROW_NUMBER/DENSE_RANK的区别是并列时的排名处理。考试时如果题目没提并列两种写法都可以如果提了“最高薪资可能有多人”就要注意返回多行是否符合题意。2.4 范式判断与事务分析考的是权衡不是死记范式判断题的套路是给一个关系模式加一组函数依赖让你判断属于第几范式并分解。事务分析题通常给一个并发调度让你判断是否可串行化。这两类题的共同点是答案不唯一但考试有标准答案。你要做的是理解标准答案背后的权衡逻辑。范式分解的核心权衡是分解越细冗余越少但连接越多查询越慢。所以3NF和BCNF的选择不是“越高越好”而是看业务对一致性和性能的侧重。事务可串行化的判断核心是看冲突操作之间有没有环。-- 验证范式分解以学生选课为例 -- 原始表SC(学号, 课程号, 成绩, 教师名) -- 函数依赖学号课程号 → 成绩课程号 → 教师名 -- 问题教师名部分依赖于课程号存在传递依赖 -- 分解为 -- SC1(学号, 课程号, 成绩) -- SC2(课程号, 教师名) -- 验证无损连接SC1 ⋈ SC2 能否还原原始表 SELECT * FROM SC1 NATURAL JOIN SC2;逻辑说明这个分解消除了传递依赖达到3NF。参数说明NATURAL JOIN会自动按同名列连接这里同名列是课程号。你要验证的是分解后连接的结果是否和原始表完全一致以及是否丢失了任何函数依赖。考试时如果要求达到BCNF还要检查每个决定因素是否都是候选键。3. 从试题到可运行验证用SQLite搭一个最小复习环境3.1 为什么选SQLite而不是MySQL或PostgreSQL复习数据库试题你不需要一个完整的数据库服务器。你需要的是一个能快速建表、插入数据、执行查询、看到结果的环境。SQLite满足这三个条件而且零配置、单文件、跨平台。MySQL和PostgreSQL当然更接近生产环境但安装和配置会消耗你本来就不多的复习时间。常见做法是用SQLite验证选择题和SQL大题用MySQL验证事务和隔离级别。因为SQLite对事务隔离级别的支持比较有限默认是SERIALIZABLE不方便演示READ COMMITTED和REPEATABLE READ的差异。但如果你只是验证SQL语法和查询逻辑SQLite足够了。# 安装SQLite多数系统自带没有的话用包管理器 # macOS: brew install sqlite # Ubuntu/Debian: sudo apt install sqlite3 # Windows: 下载 sqlite-tools 压缩包解压后把 sqlite3.exe 放到 PATH # 创建一个复习用的数据库文件 sqlite3 exam_review.db # 在SQLite提示符下建表 CREATE TABLE student ( sno TEXT PRIMARY KEY, sname TEXT NOT NULL, dept TEXT ); CREATE TABLE course ( cno TEXT PRIMARY KEY, cname TEXT NOT NULL, credit INTEGER ); CREATE TABLE sc ( sno TEXT, cno TEXT, grade REAL, PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES student(sno), FOREIGN KEY (cno) REFERENCES course(cno) );逻辑说明这三张表覆盖了试题里最常见的连接查询场景。参数说明PRIMARY KEY指定主键FOREIGN KEY指定外键NOT NULL约束非空。SQLite默认不强制外键需要执行PRAGMA foreign_keys ON;才能生效。这个细节本身就是一道选择题的考点。3.2 把试题里的SQL大题变成可执行的验证脚本复习SQL大题最有效的方式是把题目里的描述转成建表和插入语句然后自己写查询再对照参考答案。这个过程会暴露你“以为会了”和“真的会了”之间的差距。-- 插入模拟数据 INSERT INTO student VALUES (S001, 张三, 计算机); INSERT INTO student VALUES (S002, 李四, 计算机); INSERT INTO student VALUES (S003, 王五, 数学); INSERT INTO course VALUES (C001, 数据库, 4); INSERT INTO course VALUES (C002, 数据结构, 3); INSERT INTO course VALUES (C003, 高等数学, 5); INSERT INTO sc VALUES (S001, C001, 85); INSERT INTO sc VALUES (S001, C002, 90); INSERT INTO sc VALUES (S002, C001, 78); INSERT INTO sc VALUES (S002, C003, 88); INSERT INTO sc VALUES (S003, C003, 92); -- 题目查询选修了“数据库”课程且成绩大于80的学生姓名 SELECT s.sname FROM student s JOIN sc ON s.sno sc.sno JOIN course c ON sc.cno c.cno WHERE c.cname 数据库 AND sc.grade 80; -- 题目查询每个学生的总学分只算及格课程 SELECT s.sname, SUM(c.credit) AS total_credit FROM student s JOIN sc ON s.sno sc.sno JOIN course c ON sc.cno c.cno WHERE sc.grade 60 GROUP BY s.sno, s.sname;逻辑说明第一道题考三表连接加过滤第二道题考连接加聚合加过滤。参数说明JOIN默认是INNER JOIN只返回匹配的行GROUP BY后面要跟所有非聚合列否则在严格模式下会报错。SQLite对GROUP BY的约束比较宽松但考试时如果用的是MySQL的ONLY_FULL_GROUP_BY模式漏写sname就会报错。3.3 用EXPLAIN看查询计划理解试题背后的性能考点很多试题会问“哪个查询效率更高”或者“索引应该建在哪个列上”。这类题如果只背答案换个场景就懵了。用EXPLAIN看查询计划能把抽象的效率问题变成具体的扫描行数和索引使用情况。-- 在SQLite中查看查询计划 EXPLAIN QUERY PLAN SELECT s.sname FROM student s JOIN sc ON s.sno sc.sno WHERE sc.grade 80; -- 输出示例 -- SCAN sc -- SEARCH s USING INTEGER PRIMARY KEY (rowid?) -- 在sc.grade上建索引后再看 CREATE INDEX idx_sc_grade ON sc(grade); EXPLAIN QUERY PLAN SELECT s.sname FROM student s JOIN sc ON s.sno sc.sno WHERE sc.grade 80; -- 输出示例 -- SEARCH sc USING INDEX idx_sc_grade (grade?) -- SEARCH s USING INTEGER PRIMARY KEY (rowid?)逻辑说明第一次输出显示对sc表做了全表扫描SCAN建索引后变成索引查找SEARCH USING INDEX。参数说明EXPLAIN QUERY PLAN是SQLite的命令MySQL里用EXPLAINPostgreSQL里用EXPLAIN ANALYZE。考试时如果问“为什么在grade上建索引能加速”你要能说出“因为避免了全表扫描直接定位到满足条件的行”。4. 避坑复习数据库试题时最容易翻车的五个地方4.1 把参考答案当唯一真理忽略数据库差异现象试题答案写“SELECT * FROM t WHERE name LIKE %abc% 可以用索引”你背下来结果在MySQL的InnoDB上发现全表扫描。原因前缀模糊匹配LIKE abc%可以用索引但前后都带通配符LIKE %abc%通常用不了B树索引。不同数据库的优化器行为也有差异。解决遇到这类题先确认题目默认的数据库类型。如果没有指定就按标准SQL的通用行为来答同时在笔记里标注“MySQL下实际行为可能不同”。复习时用SQLite或MySQL实际跑一下EXPLAIN比背答案可靠。4.2 事务隔离级别的实验做了一半就下结论现象你在MySQL里开了两个会话想验证“不可重复读”结果发现会话A第二次读到的数据和第一次一样就以为MySQL不支持不可重复读。原因MySQL默认隔离级别是REPEATABLE READ在这个级别下确实不会出现不可重复读。你要先改成READ COMMITTED才能看到。解决实验前先确认当前隔离级别用SELECT transaction_isolation;MySQL 8.0或SELECT tx_isolation;MySQL 5.7。改级别用SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;。每次实验只改一个变量否则你分不清是隔离级别的影响还是其他配置的影响。4.3 范式分解后忘了验证无损连接和依赖保持现象你把一个表分解成三个表觉得“每个表都满足3NF了”但一连接发现数据对不上或者某个函数依赖丢了。原因范式分解有两个硬性要求——无损连接和依赖保持。只满足范式级别但不满足这两个条件的分解是无效的。解决分解后一定要做两件事。第一用NATURAL JOIN或指定列连接看能否还原原始表。第二列出原始的所有函数依赖检查每个依赖是否在某个分解后的表中仍然成立。如果某个依赖跨了多个表说明依赖丢了需要调整分解方案。4.4 SQL写对了但结果不对其实是NULL在捣乱现象你写了一个NOT IN子查询逻辑上没问题但查询结果为空。换成NOT EXISTS就对了。原因NOT IN遇到子查询结果里有NULL时整个条件会变成UNKNOWN导致没有行被返回。这是SQL里最经典的坑之一。解决用NOT EXISTS替代NOT IN或者在子查询里加WHERE col IS NOT NULL。考试时如果题目涉及“不在某个集合里”的语义优先写NOT EXISTS除非题目明确要求用NOT IN。-- 有问题的写法 SELECT sname FROM student WHERE sno NOT IN (SELECT sno FROM sc WHERE grade 60); -- 如果sc表里有sno为NULL的行上面的查询返回空 -- 修正写法一排除NULL SELECT sname FROM student WHERE sno NOT IN (SELECT sno FROM sc WHERE grade 60 AND sno IS NOT NULL); -- 修正写法二用NOT EXISTS SELECT sname FROM student s WHERE NOT EXISTS ( SELECT 1 FROM sc WHERE sc.sno s.sno AND sc.grade 60 );4.5 复习时只看不写考场上手生现象选择题和简答题背得很熟但SQL大题写的时候卡在语法上或者忘了GROUP BY后面要跟哪些列。原因阅读和书写是两种不同的认知活动。你看懂一个查询不代表你能在压力下写出来。解决每复习一道SQL大题先不看答案自己在SQLite里写一遍。写完执行看结果对不对。不对就调调到对为止。然后再看参考答案对比写法差异。这个过程比读十遍答案都管用。我一般会给自己定一个规矩每道大题至少手写两遍第一遍允许查语法第二遍闭卷写。5. 进阶用试题反向出题把复习变成验证复习到后期最有效的检验方式不是“再做一套题”而是“自己出一套题”。出题的过程会逼你从“知道答案”升级到“知道为什么这个答案值得考”。具体做法是拿一个你熟悉的业务场景比如“学生选课”或“订单管理”先设计表结构和函数依赖然后自己判断范式级别自己写查询自己设计事务并发场景。出完题后用SQLite或MySQL把整个场景跑一遍验证你的答案是否自洽。-- 自出题示例设计一个订单表包含订单号、客户号、商品号、数量、单价、下单时间 -- 函数依赖订单号商品号 → 数量商品号 → 单价订单号 → 客户号、下单时间 -- 判断范式单价部分依赖于商品号存在部分依赖不属于2NF -- 分解订单表(订单号, 客户号, 下单时间)、订单明细(订单号, 商品号, 数量)、商品表(商品号, 单价) CREATE TABLE orders ( order_id TEXT PRIMARY KEY, customer_id TEXT, order_time TEXT ); CREATE TABLE order_item ( order_id TEXT, product_id TEXT, quantity INTEGER, PRIMARY KEY (order_id, product_id) ); CREATE TABLE product ( product_id TEXT PRIMARY KEY, unit_price REAL ); -- 自问查询每个客户的总消费金额 SELECT o.customer_id, SUM(oi.quantity * p.unit_price) AS total FROM orders o JOIN order_item oi ON o.order_id oi.order_id JOIN product p ON oi.product_id p.product_id GROUP BY o.customer_id; -- 自问这个查询在数据量大时怎么优化 -- 自答在order_item的order_id和product_id上建索引在product的product_id上建主键索引 -- 如果按客户分组频繁可以考虑在orders的customer_id上建索引逻辑说明这个自出题的过程覆盖了范式判断、表设计、连接查询、聚合、索引优化五个考点。参数说明PRIMARY KEY (order_id, product_id)是复合主键保证同一订单同一商品只有一条记录。SUM(oi.quantity * p.unit_price)先算每行的金额再求和注意不要写成SUM(quantity) * SUM(unit_price)那是错的。出完题后你可以拿它去和同学交换做或者隔一周自己再做一遍。如果一周后你还能在不看答案的情况下写对说明这个知识点真的掌握了。如果写错了错的地方就是你复习的盲区。我自己的习惯是每复习完一个章节就出一套5道题的小卷子包含2道选择、1道简答、2道SQL。出完不马上做隔两天再做。这个间隔让记忆稍微冷却暴露出的问题更真实。考数据库期末也好考任何技术认证也好这套方法都比单纯刷题管用。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑