☰
数据库期末大题通关指南:ER图、SQL查询、范式分解与索引判断
2026/10/13 19:54:02 网站建设 项目流程

简介:这份中南大学数据库试题资料面向高校计算机及相关专业学生,尤其适合正在备考数据库原理课程、准备期末或考研复试的读者,用于系统梳理知识点与自测查漏。内容覆盖DBMS基础、三级模式结构、DDL/DML/DCL语言组成、ER模型与关系模型、关系代数运算、SQL语句分类、索引与约束、数据库保护(安全性、完整性、故障恢复、并发控制)以及关系规范化理论(1NF至3NF、函数依赖、模式分解)等核心考点,并配有选择题、填空题、术语解释与简答题等多种题型。资源包为1个doc文档,约164KB,结构紧凑,便于打印或电子阅读。目前已有354人学习下载。读者可借助其中的复习总纲与试卷题目,快速定位薄弱环节,理解三级模式映射、事务ACID、并发调度可串行化等易错概念,适合作为考前冲刺与日常巩固的参考材料。

1. 数据库期末题到底在考什么:从一道“学生选课”大题说起

“中南大学数据库试题”这个关键词,每年期末季都会被反复搜索。很多人拿到卷子第一反应是:SQL 我会写,范式我会背,可为什么一到综合大题就卡壳?原因往往不在知识点本身,而在于没搞清楚这门课期末到底想验证你哪几种能力。数据库原理的期末卷,通常不是考你背了多少定义,而是考你能不能把“概念—模型—SQL—优化”这条链路走通。一道典型大题会给你一个“学生选课”或“图书借阅”场景,让你画 ER 图、转关系模式、写查询、判断范式,最后再问一句“这个索引该不该建”。它真正想筛掉的,是只会孤立背知识点、无法把需求翻译成表结构和语句的人。这篇文章面向正在备考数据库原理的本科生,也面向想系统梳理 SQL 与关系设计的自学者,我会按期末卷最常见的出题顺序,把每一类题型的解法、参数和踩坑点拆开讲,让你拿到卷子知道先写什么、后写什么。

2. 从 ER 图到关系模式:大题第一问怎么拿满分

2.1 先判断实体、属性、联系,别急着画图

期末大题第一问通常是“根据描述画出 ER 图”。很多人一上来就画矩形,结果漏了联系或把属性错当实体。稳妥做法是先做三件事:圈出所有名词,标出哪些是实体、哪些是属性;找出动词,判断是一对一、一对多还是多对多;确认有没有“弱实体”或“多值属性”。以“学生选课”为例,“学生”“课程”是实体,“选课”是联系,而“成绩”是联系上的属性,不是学生的属性。这个判断直接决定后面关系模式的数量。

常见做法是先用文字列出三元组:实体—联系—实体。比如“学生—选修—课程”是多对多,必须单独成表;“班级—拥有—学生”是一对多,可以在学生表里加班级号外键。多值属性比如“联系电话”如果有多个,要么单独建表,要么在关系模式里拆出去。期末阅卷时,ER 图扣分最狠的就是联系类型标错和主键没画下划线。

提示:画 ER 图时先用铅笔标出每个实体的候选键,再决定主键。候选键选错,后面所有外键都会跟着错。

2.2 转换规则:1:1、1:N、M:N 分别怎么落表

ER 图转关系模式有固定规则,但期末卷常在这里设陷阱。下面这张表是我自己整理时最常用的对照,考试前默写一遍基本不会乱。

联系类型转换方式外键放在哪典型例子
1:1任一方加对方主键作外键通常放在参与度低的一方班级与班长
1:N在 N 方加 1 方主键作外键多的一方班级与学生
M:N单独建联系表双方主键组合成主键学生与课程
多值属性单独建表原实体主键加属性列学生与电话

转换时最容易翻车的是把 M:N 联系硬塞进某一张实体表,导致数据冗余和更新异常。比如把“选课”直接写成学生表里的一个字段,后面查“某门课有多少人选”就会非常别扭。正确做法是建一张SC(sno, cno, grade),主键是(sno, cno),两个外键分别指向学生表和课程表。

2.3 用一段 SQL 验证你的关系模式是否自洽

关系模式写完不要直接过,用建表语句验证一遍。下面这段代码可以在本地 SQLite 或 MySQL 里跑,能建成功说明主外键引用顺序没写反。

-- 学生表:sno 为主键 CREATE TABLE student ( sno CHAR(10) PRIMARY KEY, sname VARCHAR(20) NOT NULL, cno CHAR(6), -- 班级号,外键指向 class FOREIGN KEY (cno) REFERENCES class(cno) ); -- 课程表:cno 为主键 CREATE TABLE course ( cno CHAR(6) PRIMARY KEY, cname VARCHAR(30) NOT NULL, credit DECIMAL(2,1) ); -- 选课表:多对多联系,主键为组合键 CREATE TABLE sc ( sno CHAR(10), cno CHAR(6), grade DECIMAL(4,1), PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES student(sno), FOREIGN KEY (cno) REFERENCES course(cno) );

这段代码的逻辑是:先建被引用的class和student,再建course,最后建sc。参数上注意CHAR和VARCHAR的区别,学号、课程号长度固定用CHAR,姓名用VARCHAR。成绩用DECIMAL(4,1)能存 100.0 这种一位小数。如果建表时报“foreign key mismatch”,先检查被引用列是不是主键或唯一键。期末卷上虽然不跑代码,但心里过一遍建表顺序,能避免外键指向不存在的表这种低级错误。

3. SQL 查询题:从单表到嵌套,阅卷人想看什么

3.1 单表查询别丢分:WHERE、ORDER BY、LIMIT 的顺序

单表查询是送分题,但每年都有人因为写错执行顺序丢分。SQL 的逻辑执行顺序是FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT。这意味着WHERE里不能用SELECT中定义的别名,而ORDER BY可以。期末常考“查询成绩大于 90 分的学生,按成绩降序,只显示前 10 条”,正确写法是:

SELECT sno, cno, grade FROM sc WHERE grade > 90 ORDER BY grade DESC LIMIT 10;

这里WHERE过滤行,ORDER BY排序,LIMIT截断。如果题目要求“查询平均分大于 90 的课程”,就必须用GROUP BY加HAVING,因为聚合条件不能写在WHERE里。参数上注意DESC只作用于紧挨着它的列,多列排序要每列都写。

3.2 嵌套查询与连接查询:什么时候必须用 EXISTS

期末卷喜欢考“查询选修了全部课程的学生”或“查询没选过某门课的学生”。这类题用NOT EXISTS最稳,因为NOT IN遇到NULL会返回空结果,是个经典坑。比如“查询没有选修 C01 的学生”:

SELECT sname FROM student s WHERE NOT EXISTS ( SELECT 1 FROM sc WHERE sc.sno = s.sno AND sc.cno = 'C01' );

这段代码的逻辑是:对外层每个学生,检查sc里是否存在他的 C01 选课记录,不存在就输出。SELECT 1只是占位,不关心返回什么。参数上注意相关子查询要引用外层别名s.sno。如果换成NOT IN,当sc.sno里有NULL时,整个条件会变成未知,结果直接为空,这就是很多人查不出数据的原因。

3.3 聚合与分组:GROUP BY 的列必须出现在 SELECT 里吗

标准 SQL 要求SELECT里的非聚合列必须出现在GROUP BY中,但 MySQL 的ONLY_FULL_GROUP_BY模式关闭时允许偷懒。期末卷按标准答案判,所以别赌。比如“查询每门课程的平均分和选课人数”:

SELECT cno, AVG(grade) AS avg_grade, COUNT(*) AS cnt FROM sc GROUP BY cno HAVING AVG(grade) >= 60;

这里cno在GROUP BY里,AVG和COUNT是聚合。HAVING过滤分组后的结果,不能用WHERE替代。参数上COUNT(*)统计所有行,COUNT(grade)会忽略NULL,如果成绩允许为空,两者结果不同。期末卷常在这里设“成绩为空是否计入人数”的陷阱,看清题目再选。

4. 范式判断与分解:3NF、BCNF 到底怎么区分

4.1 函数依赖先找候选键,再谈范式

范式题的第一步永远是找候选键。给定关系模式R(A,B,C,D)和函数依赖集F={A→B, B→C, C→D},候选键是A,因为A能推出所有属性。找候选键的方法:把只出现在左边、不出现在右边的属性作为起点,然后看闭包是否覆盖全部属性。候选键找错,后面 2NF、3NF 的判断全错。

判断 2NF 看有没有非主属性部分依赖候选键。如果候选键是单属性,一定满足 2NF。判断 3NF 看有没有非主属性传递依赖候选键。比如A→B, B→C,C传递依赖A,就不满足 3NF。BCNF 更严:每个决定因素都必须是候选键。A→B中A是候选键,B→C中B不是候选键,所以不满足 BCNF。

4.2 分解到 3NF 的合成法与分解法

期末常要求“将 R 分解为 3NF 并保持函数依赖”。合成法步骤:先求最小函数依赖集,再把每个依赖的左右属性合成一个关系模式,最后如果所有模式都不包含候选键,加一个候选键模式。以F={A→B, B→C, C→D}为例,最小集就是它本身,合成后得到R1(A,B)、R2(B,C)、R3(C,D),候选键A已经在R1里,分解完成。

分解法用于 BCNF,步骤是:如果某个模式不满足 BCNF,找到违反的决定因素X→Y,把模式拆成X∪Y和R-Y,递归直到全部满足。分解法可能丢失函数依赖,期末如果要求“既无损又保持依赖”,优先用合成法做 3NF。

4.3 无损连接判断:一张表搞定

判断分解是否无损,用 Chase 算法或矩阵法。以R(A,B,C)分解为R1(A,B)和R2(B,C)为例,公共属性是B,如果B是R1或R2的候选键,则无损。更通用的矩阵法:画一张表,行是分解后的模式,列是原属性,初始填a或b,然后按函数依赖反复修改,直到出现一行全是a。期末卷上如果只给两个模式分解,直接看公共属性是不是其中一个的候选键,能省不少时间。

5. 索引与事务:期末卷最后一道大题怎么答到点上

5.1 索引该不该建:看选择性和更新频率

期末最后一道大题常给一个查询,问“是否需要建索引,建在哪些列上”。答题模板:先看WHERE、JOIN、ORDER BY用到的列;再看列的选择性,即不同值比例,比例越高越适合建索引;最后看表的更新频率,更新频繁的列建索引会拖慢写入。比如“查询某班级某门课的平均分”,WHERE用到cno和cno,如果班级号选择性高,可以在sc(cno, cno)上建复合索引,注意顺序把选择性高的放前面。

注意:索引不是越多越好。期末卷如果问“为什么不在性别列建索引”,标准答案是性别只有两个值,选择性太低,全表扫描可能更快。

5.2 事务隔离级别与并发问题

事务题常考“脏读、不可重复读、幻读”分别对应哪个隔离级别。记住表格:读未提交允许脏读;读已提交禁止脏读但允许不可重复读;可重复读禁止不可重复读但允许幻读;串行化全禁止。期末可能给一段并发执行序列,让你判断最终结果。用两阶段锁协议分析:事务在读写前加锁,提交后释放。如果两个事务交叉加锁,可能死锁,数据库会选一个回滚。

5.3 一道综合题的完整答题顺序

假设题目给“学生选课”场景,要求写查询“查询平均分最高的课程号”。答题顺序:先写子查询求每门课平均分,再取最大值,最后匹配课程号。

SELECT cno FROM sc GROUP BY cno HAVING AVG(grade) = ( SELECT MAX(avg_grade) FROM ( SELECT AVG(grade) AS avg_grade FROM sc GROUP BY cno ) AS tmp );

这段代码的逻辑是:内层先算每门课平均分,中层取最大值,外层找出平均分等于最大值的课程。参数上注意派生表必须起别名tmp,否则 MySQL 报错。期末卷上如果不用派生表,也可以用ORDER BY AVG(grade) DESC LIMIT 1,但要注意并列第一的情况,LIMIT 1只返回一个。

6. 考前一周怎么练:把错题变成可复现的检查清单

最后一周不要再刷新题,把之前做错的题按题型归类,每类写一张检查清单。比如 ER 图题检查:实体是否漏、联系类型是否标、主键是否画线、多值属性是否拆表。SQL 题检查:WHERE和HAVING是否混用、NULL是否处理、GROUP BY列是否完整。范式题检查:候选键是否找对、部分依赖和传递依赖是否区分、分解是否无损。

我自己的习惯是考前三天把最常错的五道题重新手写一遍,不看书,写完对照答案用红笔标出差异。这个方法看起来笨,但能暴露“以为自己会了”的盲区。数据库期末卷的套路其实很固定,把 ER 转换、嵌套查询、范式分解、索引判断这四类题各练透三道,基本就能覆盖 80% 的分数。希望帮到你。

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

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

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

立即咨询