简介:中南大学数据库试题是一份针对数据库原理课程期末备考的实用资料,适合高校学生、考研复习者及需要巩固数据库基础知识的学习者。内容围绕数据库管理系统(DBMS)核心知识展开,涵盖数据模型、关系模型、SQL语言、数据库保护、并发控制与关系规范化等高频考点,并配有复习总纲与试卷例题,便于系统性查漏补缺。压缩包内共1个文件,以doc格式提供,大小164KB,打开即可直接阅读。目前已有353人学习下载,适合在考前快速梳理重点。资料中包含选择题、填空题、术语解释和简答题等典型题型,并附有部分参考答案与解题思路,可帮助读者熟悉中南大学数据库课程的出题风格,检验自身掌握程度,提升应试效率。
1. 一套数据库期末试题,为什么值得逐题拆着看
数据库这门课有个很奇怪的现象:平时写业务代码能跑通,一到期末考试就翻车。中南大学数据库试题这套题,恰恰是把这个矛盾摊开给你看的典型样本——它不考你背了多少概念,而是考你能不能把关系代数、SQL、范式、事务这些知识在限时场景里串起来用。很多人觉得“我会写增删改查就够了”,但试卷里的题目会追问你:为什么这个查询走了全表扫描、这个事务在 RR 级别下会不会死锁、这个表设计到底满足第几范式。把这套题拆透,本质上是把数据库从“会用”往“懂原理”推了一把。适合正在备考期末的学生,也适合想检验自己基础是否扎实的开发者。
2. 中南大学数据库试题考什么:题型分布与复习优先级
2.1 固定题型背后有一套稳定的考点矩阵
数据库期末试题的出题风格,多年来保持着一个相当稳定的结构。别把这套题当成一份普通练习册,它更像是一张覆盖考点的地图。选择题、填空题、简答题、综合设计题、SQL 编程题是骨架,每种题型背后都对应着明确的知识模块。选择题偏爱基本概念辨析,比如三级模式结构、数据独立性、关系完整性;填空题喜欢抠定义里的关键字眼,比如笛卡尔积的基数计算、范式的定义;综合设计题则固定在 E-R 图转关系模式、关系代数表达式、范式分解这几个考点上来回打转。
从复习投入产出比来看,这套题的价值不在于“答案是什么”,而在于它暴露了考点之间的权重关系。你不需要把教材从头背到尾,只需要把高频考点按分值排个序,就能知道时间该花在哪。通常情况下,SQL 编程和关系代数占了卷面的大头,其次才是事务并发和范式理论,最后才是数据库安全性、恢复技术这些记忆性内容。搞清楚这个权重,复习顺序就自然出来了。
2.2 SQL 与关系代数占分最重,先啃硬骨头
翻开任何一年的数据库期末试卷,SQL 题目一定是压轴的存在。它通常分成两到三问:先是让你根据表结构写查询语句,再是让你用关系代数表达式表达同样的查询,最后可能还跟一个更新操作,比如删除某类记录、修改某列值。这类题占分通常在 30 分上下,是最值得投入时间的板块。
关系代数考察的是你没有 SQL 引擎兜底时,能不能用投影、选择、连接、除运算这些东西精确描述一个查询。很多同学能写出 SQL,但写关系代数就卡壳,根源在于对“连接之后再做选择,还是选择之后再连接”这种执行顺序没有感觉。我的建议是先做完所有 SQL 题,再用关系代数的符号体系重新表述一遍,这样两个知识模块就互相印证了。做得多了你会发现,SQL 里每一个子句都能映射到关系代数的一个算子,反过来也一样。
2.3 三大范式与事务并发:理论题的主战场
范式判断题是填空题和简答题的常客,常见的问法是“这个关系模式最高属于第几范式,为什么”,或者“把该模式分解到 3NF,写出分解结果”。这类题的难点不在于理解 1NF、2NF、3NF 的定义,而在于判断候选键和函数依赖。一旦候选键找错,后面的范式判断和分解全盘皆输。
事务并发部分则偏好出这种题:给一个并发调度序列,问你是否存在冲突、是否可串行化,或者问在某个隔离级别下会发生什么异常。脏读、不可重复读、幻读这三个词几乎年年出现,但考法不是让你默写定义,而是给你一个具体的执行时序,让你判断发生了什么。所以在复习的时候,一定要拿纸笔把每个隔离级别下可能出现的异常画一遍,光看是记不住的。
2.4 按题目优先级排复习顺序
我给备考同学的建议是先做题型分析,再定复习路线。下面是常见的分值段分布和对应的复习优先级:
| 题型 | 大致分值 | 核心考点 | 建议优先级 |
|---|---|---|---|
| 选择题 | 20 分上下 | 基本概念、约束、存储、安全 | 低,靠刷题带过 |
| 填空题 | 10 分上下 | 术语定义、计算公式 | 低,零散记忆 |
| 关系代数题 | 15 分上下 | 选择、投影、连接、除运算 | 高,必须练熟 |
| SQL 编程题 | 25 分上下 | 多表连接、聚合、子查询、更新 | 高,占分最重 |
| 范式与设计题 | 15 分上下 | 候选键、范式判断、模式分解 | 高,易丢分 |
| 事务并发题 | 10 分上下 | 隔离级别、冲突、可串行化 | 中,需要理解 |
| 简答题 | 5 分上下 | 日志、备份、恢复、安全 | 低,考前背熟 |
这个表不是让你死记,而是帮你把有限的复习时间压到得分效率最高的题目上。所谓及格不难、高分不易,差距就在 SQL 题和范式题的熟练度上。
3. 把 SQL 题做对:从自然语言到可执行语句的转换套路
3.1 先把题目翻译成关系代数骨架
做 SQL 题最忌讳上来就写 SELECT 语句。自然语言描述的查询往往有歧义,直接动手容易漏条件或者把连接方向搞反。我习惯的步骤是先把题目拆成骨架:查哪张表、要哪几列、有哪些过滤条件、需不需要分组、表之间怎么关联。
写 SQL 的核心步骤,是把自然语言逐句翻译成关系代数算子。比如题目说“查询选修了所有课程的学生姓名”,这句话翻译成除运算或者 NOT EXISTS 子查询,都比直接拼 SQL 更接近正确答案。看到“所有”这个词,先想除法或 NOT EXISTS 而不是 JOIN;看到“没有选修过”这样的否定表达,用 NOT IN 或 NOT EXISTS 比外连接加 IS NULL 更稳妥。
-- 查询选修了全部课程的学生姓名 SELECT s.sname FROM student s WHERE NOT EXISTS ( SELECT 1 FROM course c WHERE NOT EXISTS ( SELECT 1 FROM sc WHERE sc.sno = s.sno AND sc.cno = c.cno ) );这段代码是“选修了所有课程”的经典写法。外层 NOT EXISTS 针对每一门课,内层 NOT EXISTS 检查该学生是否选了这门课。如果存在一门课该学生没选,内层 NOT EXISTS 为假,外层条件就不成立,这个学生被过滤掉。参数说明:sno 是学号,cno 是课程号,sc 是选课关系表;这套命名在数据库教材里基本通用,不过实际表名要以卷面为准。
3.2 连接条件与别名:大多数 SQL 题的丢分点
连接查询是 SQL 大题里出现频率最高的考点,一般以三张表的连接收尾:学生表、课程表、选课表。丢分的常见原因不是不会写 JOIN,而是连接条件写错或漏写。三表连接至少要有两个连接条件,少一个就变成笛卡尔积,结果行数暴涨。题目如果要求显示学生姓名、课程名和成绩,那必然要经过选课表这个中间表,学生表和课程表之间不存在直接关联,硬连就是错。
给表起别名不是可选项,而是必选项。多表查询里一旦出现同名列,比如多个表里都有 sname 或者 cname,不带别名只能用全表限定名救场,写起来又长又容易错。考试时别嫌麻烦,每个表都起一个简短的别名,一方面压缩代码量,另一方面也降低自己看花眼的概率。
-- 查询选了“数据库原理”这门课且成绩大于 85 分的学生姓名 SELECT s.sname, sc.grade FROM student s JOIN sc ON s.sno = sc.sno JOIN course c ON sc.cno = c.cno WHERE c.cname = '数据库原理' AND sc.grade > 85 ORDER BY sc.grade DESC;这里的连接顺序是 student 先连接 sc,再连接 course。WHERE 里的过滤条件在连接完成之后统一执行,所以既可以过滤课程名,也可以过滤成绩,不会影响连接结果。ORDER BY 后面可以用 sc.grade 或者列别名,但注意聚合列不允许直接出现在 ORDER BY 里除非配合 GROUP BY。如果题目问的是“每个学生的选课门数和平均分”,那就要换成 GROUP BY 的写法,这条语句就不适用了。
3.3 聚合与分组:WHERE 和 HAVING 的过滤时机
聚合查询每年都会考,而且考法很固定:查询每个系的平均年龄、查询选课门数超过 3 门的学生、查询平均分最高的课程。这些题的核心是搞清楚 WHERE、GROUP BY、HAVING 的执行顺序。WHERE 在分组之前过滤行,HAVING 在分组之后过滤组,这个顺序是你判断该用哪个条件的关键。
例如“查询选课门数大于 3 且成绩都及格的学生”,这里有两个条件:一个是必须选了 3 门以上的课,这是组级条件,要放 HAVING;另一个是成绩都及格,看起来像行级条件,但“都及格”其实要落到组内最小成绩上,也是组级条件。如果直接用“成绩大于 60”做 WHERE 过滤,就会把挂科记录删掉,导致统计的选课门数变少,明明选了 5 门挂了一门也被算作选了 4 门,查出来的结果就不对。
-- 查询选课门数超过 3 门、且所有课程均及格的学生学号 SELECT sno FROM sc GROUP BY sno HAVING COUNT(*) > 3 AND MIN(grade) >= 60;这段代码的关键在于用 MIN(grade) 来表达“全部及格”,只要组内最低分大于等于 60,就没有不及格的记录。COUNT(*) 统计的是分组内的行数,即选课门数。注意这里没有 WHERE 子句,因为如果把 grade >= 60 放到 WHERE 里,实际上先把不及格的记录过滤掉了,再做分组统计,门数会失真。这个坑非常隐蔽,属于每年都有人踩的典型错误。血泪经验:凡是条件里带“每个”“所有”“全部”这类词,先想清楚它作用在行上还是组上。
3.4 用最小样例数据验证 SQL 结果
考试没有执行环境,但你可以在备考时用本地数据库把每道题跑一遍。我一般会建三张最小表,每张表只放三条数据,专门用来验证语义边界。测试数据的设计原则有两条:一是要有重复值,测试分组和去重;二是要有满足条件和不满条件的边界记录,比如成绩正好等于 60 分的记录,用来验证 >= 和 > 的区别。
-- 创建一个最小验证环境 CREATE TABLE test_sc ( sno VARCHAR(10), cno VARCHAR(10), grade INT ); INSERT INTO test_sc VALUES ('s1', 'c1', 90), ('s1', 'c2', 60), ('s2', 'c1', 55);在这个最小环境里跑上一节的 HAVING 语句,结果应该是 s1 被查出来,因为它选了两门课且最低分是 60;而 s2 选了一门课且不及格,被排除。如果 WHERE 版本,s2 的记录会在分组前被过滤掉,那它就不会出现在结果里,虽然语义上它本来也不该出现。关键是当你写的查询涉及更复杂的分组条件时,这样的最小样例能帮你快速看清过滤时机带来的差异。这个习惯在考试时还能反过来用:遇到拿不准的 SQL,用草稿纸画一个小表,手动推演每一行的流转,比瞎猜靠谱得多。
4. 范式判断、事务与并发控制:需要背成条件反射的结论
4.1 范式判断的抄近路:从函数依赖画起
范式题考的不是背定义,而是能否快速找候选键、判断部分依赖和传递依赖。我的套路是先画出所有函数依赖,再找候选键。找候选键有个实用方法:先找出所有从来没出现在函数依赖右侧的属性,它们是候选键的必要组成部分;然后试着扩展它们,看能否推导出所有属性。
有了候选键之后,范式的判断就变成机械操作。2NF 要求非主属性完全依赖于候选键,如果候选键是组合键,而某个非主属性只依赖其中一部分,那就是部分依赖,不满足 2NF。3NF 要求没有传递依赖,即非主属性不依赖于其他非主属性。每一层都是在前一层基础上加约束,所以判断顺序是固定的。
例如给定关系模式 R(A, B, C, D),函数依赖为 AB→C、C→D。候选键是 AB,因为 AB 能推出 C,C 又推出 D。非主属性 C 和 D 都完全依赖于 AB,所以满足 2NF;但 C→D 意味着 D 传递依赖于 AB,不满足 3NF。分解到 3NF 的常规做法是把 C→D 拆出去,得到 R1(A, B, C) 和 R2(C, D),在这个过程中要保证函数依赖不丢失。这套流程不玄学,多做三遍就能条件反射。
4.2 隔离级别与异常对照表
事务这块最常考的是隔离级别和并发异常之间的对应关系。题目给你一个调度序列,问你哪一级隔离级别下不会出现什么问题。背这个表比背定义更直接,因为考试就是按表出题的。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read Uncommitted | 可能 | 可能 | 可能 |
| Read Committed | 不可能 | 可能 | 可能 |
| Repeatable Read | 不可能 | 不可能 | 可能(MySQL InnoDB 可避免) |
| Serializable | 不可能 | 不可能 | 不可能 |
需要特别说明的是 MySQL 的 InnoDB 在 Repeatable Read 级别下通过间隙锁基本杜绝了幻读,但教材上经典的 SQL 标准定义里,RR 级别仍然允许幻读。考试如果明确提到“按 SQL 标准回答”,就按表格来;如果提到 MySQL InnoDB,要注意间隙锁这个例外。不要在这种地方犯低级错误。判断题目类型时,先看题干里有没有数据库关键字,没有就默认教材标准。
4.3 可串行化判定:优先图画法
并发调度的可串行化判断是一个必考题型。给一个调度序列,比如 T1 读 A、T2 写 A、T1 写 B、T2 读 B,让你判断是否冲突可串行化。画优先图的步骤是先找冲突:不同事务对同一数据项进行读写或写写操作,且后一个操作在前一个操作之后。然后从 Ti 到 Tj 画一条有向边,表示 Ti 必须先于 Tj 执行。最后看有没有环,有环则不可串行化,无环则可以对图做拓扑排序,得到等价的串行顺序。
画图时要特别注意事务内部的多个操作也会和其他事务产生边。不要只盯着相邻的两条记录看,要全局扫描。题干里的事务越长,越要小心漏边。我习惯用表格列出所有冲突对,再依次连线,这样能避免跳着看漏掉隐藏的冲突关系。这类题一旦漏边,整个串行化判断就反了,分数丢得可惜。
4.4 B+ 树索引的代价模型:为什么索引不是越多越好
索引部分在试题里通常以选择题和简答题出现,问 B+ 树相比 B 树的优势,或者给定一个查询条件让你判断能不能用上联合索引的最左前缀。第一个问题标准答案是 B+ 树非叶节点不存数据,单节点能容纳更多键值,树更矮,且叶子节点用链表连接,适合范围扫描。第二个问题则考最左前缀原则,比如联合索引 (a, b, c),查询条件只有 b 和 c 时用不上索引,因为跳过了最左列 a。
这块还有一个高频考点:为什么索引会降低插入和删除的性能。原因是每插入一条记录都要维护索引结构,涉及节点分裂和页写入。理解了代价模型,就能判断“在分数列上建索引好不好”这类场景题。如果表经常做范围查询,建索引收益高;如果表写入频繁且很少按该列查询,索引就是负担。这道题的答法不是背优缺点,而是根据题目给的读写比例做分析。
5. 刷题避坑:这套数据库试题里最容易翻车的 5 个细节
5.1 现象:连接查询结果行数翻倍或多出大量无关行
有一次模拟训练,一道三表连接查询,我写出来的语句跑出来的行数比手算答案多出一倍。排查后发现是多加了表别名之间的交叉连接,两个连接条件少写了一个。三张表连接至少需要两个关联条件,少了任何一个都会退化成笛卡尔积,结果行数变成两张表行数的乘积。
原因通常是拿到题目先写 SELECT,没有先理清表之间的关联路径。解决方法是写 SQL 之前先画出表关系图,标清楚哪两张表有外键关联,再动笔。写完数一遍 WHERE 或 ON 里的关联条件数量,关联条件数应该等于连接的表数减一。这个校验规则简单到不容易忘,但能拦住大部分低级失误。
5.2 现象:分组聚合查询丢数据,统计结果对不上
考过一道“统计每门课的选课人数并显示选课人数大于 50 的课程”,我写出来的结果里,有些选课人数是 0 的课程直接消失了。原因是用了 INNER JOIN,把没学生选的课程过滤掉了。题目没有明确要求“只显示有选课的课程”时,保留所有课程应该用 LEFT JOIN,再配合 COUNT(sc.cno) 而不是 COUNT(*),否则连接后没匹配上的那些行会被计数成 1。
解决方案是看到“每门课”“每个系”这种全量列举的词,立刻警惕是否需要保留左表的全量数据。连接类型的选择也属于踩坑高发区,LEFT JOIN 和 INNER JOIN 在这个场景下的结果差异不是细节,而是方向性的错误。解题时若题干没有明确排除空值记录,优先考虑 LEFT JOIN 更稳妥。
5.3 现象:范式判断题反复出错,候选键找错导致连环错
一次练习里我把候选键认定错了,导致后面判断 2NF、3NF 全部跟着错,一道 15 分的题只拿到 2 分。原因是我把函数依赖右侧的属性也纳入候选键考虑,搞混了“候选键能推出所有属性”和“候选键包含所有属性”这两个概念。候选键是从左侧属性里找的,不包含右侧才出现的属性,除非它们之间还存在循环依赖。
修正方法是每次做题前先列一遍全部函数依赖,把只出现在左侧的属性圈出来,从它们开始推导。如果无法推导出全集,再尝试加入出现在右侧的属性作为候选键组成部分。这个算法虽然笨,但不会错。范式的判断链一旦第一环出错,后面的分解题基本拿不到分了。
5.4 现象:事务题把隔离级别和锁的粒度搞混
考试问“在 Read Committed 级别下该调度是否会出现不可重复读”,我答案写反了。原因是把隔离级别直接等价成锁的粒度,以为读提交就是行级锁保证一切。实际上读提交只是保证读到的都是已提交的数据,不保证同一条记录两次读取结果一致。行级锁、表级锁是实现手段,隔离级别是行为约定,两者不在一个层面。
解决方法是把隔离级别的行为表现和常见实现分开记忆:先背行为(能不能脏读、能不能不可重复读),再背实现(MVCC、共享锁、排他锁、间隙锁)。考试问行为,你就答行为;问实现,你再答实现。不要在一个层面里混着说。如果题目给了具体锁的类型,那反而简单,逐条分析加锁时序即可。
5.5 现象:本地数据库跑通的和卷面答案不一致
MySQL 的某些语法在标准 SQL 里不兼容,比如 LIMIT 子句、字符串拼接的写法、外连接的关键字。同一道题,用 MySQL 跑出的正确答案,按教材标准语法写可能直接被判错。遇到“按标准 SQL 作答”的要求,就别把 MySQL 专有写法往上堆。
规避方法是备考阶段就给本地数据库建立一个“标准 SQL 模式”的自觉:查资料时优先确认标准写法,然后测试 MySQL 的兼容写法差异。碰到 LIMIT、ON DUPLICATE KEY UPDATE 这类方言,标注在后面不写进卷面。反向操作同样存在,如果你平时用的是 Oracle 或 SQL Server,要特别注意分页查询的写法完全不一样,别把 ROWNUM 或者 TOP 直接写在卷子上。
6. 把一套题盘成查漏补缺工具:错题矩阵与二次自测
6.1 给每道错题打上考点标签
做完一遍完整试卷后,不要急着对答案,先把每道错题对应到具体的知识点上。我给每道错题建一条记录,格式是“题号 + 考点标签 + 错因类型”。考点标签用统一词表,比如“三表连接”“GROUP BY 过滤时机”“候选键求解”“隔离级别判读”。这样做的目的是让问题显性化,你会发现错误并不是均匀分布的,而是集中在某两三个知识点上。我当年错题最集中的区域是 HAVING 的过滤时机和候选键的求解方法,针对性补了两次专项练习之后就基本消除了。
6.2 间隔 7 天做一次同类题二次自测
同一个考点只做一遍题,记忆留存率并不高。我采用的很简单的时间间隔是:首次错题订正当天重做一遍同类题,第 7 天再重做一遍。第二次重做,重点在于不看任何笔记,完全凭记忆和推理独立完成。这一步能区分出哪些知识你是真的会了、哪些是短期记忆。二次自测如果仍然出错,就把这道题标记为“顽固错题”,在考前最后两天专门再看一遍。
6.3 计时训练与易错点笔记
考试丢分不只是知识问题,时间分配也很关键,SQL 大题和范式分解题都要留足时间。备考后期,我建议把整套卷子当成模拟考试来计时,宁可前 60 分钟做得慢一点,也要保证后面的大题有 40 分钟以上。计时过程中留意自己在每道题上的耗时,如果一道选择题磨了 5 分钟还没结论,果断标记跳过,先拿稳后面的分。
我说一句教训:最初复习时我沉迷于反复看教材和笔记,后来才明白刷题和整理错题比单纯看书有用得多,同样的时间投入,后者能多拿 10 到 15 分。把一套真题认真拆解两遍,比泛泛地做完三套模拟题更扎实。每道错题都是一个具体的漏洞,堵住一个就实实在在多一分。希望这些方法能帮到你,也祝你备考顺利、考试稳定发挥。
本文还有配套的精品资源,点击获取