简介:面向高校本科生的MySQL数据库原理与应用期末考试复习资料,完整覆盖高校邦平台网上终考常见考点,适合备考期末及巩固关系型数据库基础。压缩包内为1个PDF文件,大小约267KB,按选择题与判断题形式编排,共含30道单选题和12道判断题,知识点涵盖数据库创建、SQL函数、事务控制、索引、主键、字段类型、数据存储、查询排序、性能优化与数据库恢复等。已有3767人学习使用,备考者可据此快速定位薄弱环节。除基础概念外,资料还对SUM求和、MAX取最大值、%通配符、ORDER BY排序、DELETE/UPDATE/SELECT命令以及系统表与用户表、数据库管理系统软件识别等易混淆内容作了例题式解析,适合考前集中刷题、对照复习,帮助考生熟悉题型并理解MySQL核心原理。
1. 期末考前一周,MySQL复习资料到底该怎么用才不浪费
《(完整)MySQL数据库原理与应用期末考试复习资料.pdf》这类文档,每年考前都会在学生群里流传几轮。但多数人拿到手后的真实状态是:从头翻到尾,感觉什么都眼熟,合上PDF,发现连一条完整的SELECT都写不利索。问题不在资料本身,而在于你用错了复习方式——把一本本来该当“索引手册”用的资料,硬生生读成了小说。
这份复习资料解决的诉求很具体:考前一两周内,把数据库原理的知识框架、SQL语法细节、事务与索引的底层逻辑、常见考题套路一次性串起来。它适合两类人:一类是上课听过但没动手练过的,需要用最短路径把理论和实操接上;另一类是刷过一些题但知识是散的,需要一张能挂住所有知识点的网。这篇文章不替你把PDF重抄一遍,而是告诉你:拿到这类复习资料后,按什么顺序看、哪些地方必须动手敲、哪些细节是考场上的高频失分点。
先把结论放在前面:MySQL期末复习,死记硬背SQL语法是性价比最低的路径。高回报的动作是——把ER图转成建表语句、把一条UPDATE的执行过程讲清楚、把事务隔离级别用两个并发场景自己演一遍。这套动作的载体,就是你手里的PDF和一台本地MySQL。
2. 先搭学习环境:用 docker 起一个 MySQL 8.0,把资料里的例子全部跑一遍
2.1 为什么建议用 docker 而不是在本机装 MySQL
很多复习资料开头会讲安装,但学生机的情况千奇百怪:有的是Windows,有的是macOS,还有的Linux发行版自带的是MariaDB。如果你按资料里的某一段安装教程走,很可能卡在初始化密码、字符集、服务启动这类环境问题上,白白消耗一晚上。更稳的做法是用docker起一个一次性实例,用完即弃,不污染本机环境,也能随时删掉重来。
另一个实际原因是:MySQL 5.7和8.0在认证插件、默认字符集、窗口函数支持上有差异。期末考题如果涉及WITH语法或者ROW_NUMBER(),5.7会直接报错,但资料里未必会标注版本差异。用8.0镜像,能保证和绝大多数教材、考题保持一致。
2.2 最小可用命令:建容器、进交互、装测试数据
# 拉取并启动 MySQL 8.0 容器,root 密码设为 123456,宿主机映射 3306 端口 docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql:8.0 # 等待容器初始化完成后,进入 MySQL 交互终端 docker exec -it mysql8 mysql -uroot -p123456参数说明:-d表示后台运行容器,--name给容器命名方便后续管理,-p 3306:3306把容器内默认端口映射到宿主机,这样Navicat或DataGrip也能连接。MYSQL_ROOT_PASSWORD是初始化时指定的root密码,仅用于本地练习,别把这个密码习惯带到生产环境。如果3306端口被占用,把左边的端口改成3307就行。
进到MySQL交互终端后,先确认版本和字符集,再建一个专门的练习库:
-- 查看版本,确认是 8.0 而不是 5.7 SELECT VERSION(); -- 查看默认字符集,考试和实操都建议统一用 utf8mb4 SHOW VARIABLES LIKE 'character_set_server'; -- 建练习库,指定字符集 CREATE DATABASE IF NOT EXISTS school DEFAULT CHARACTER SET utf8mb4; USE school;这里有个细节值得注意:utf8mb4和utf8的差别。MySQL的utf8实际是utf8mb3,只支持基本多语言平面,存emoji和部分生僻字会报错。资料里如果只写了“utf8”,你现在就该知道这是个坑。考场上写建库语句时,把字符集补成utf8mb4,是能加印象分的动作。
2.3 把资料里的ER图变成SQL:建表语句的三种练习节奏
复习资料里一定会有一张学生-课程-成绩的ER图,这是《数据库原理》教材的标配。别只看图,要动手把图翻译成建表语句,这是从“原理”到“应用”的第一步。
-- 学生表:学号是主键,姓名非空,性别有默认值 CREATE TABLE student ( sno CHAR(9) PRIMARY KEY, sname VARCHAR(20) NOT NULL, ssex CHAR(2) DEFAULT '男', sage INT, sdept VARCHAR(20) ); -- 课程表:课程号主键,课程名唯一 CREATE TABLE course ( cno CHAR(4) PRIMARY KEY, cname VARCHAR(40) NOT NULL, cpno CHAR(4), ccredit INT ); -- 选课表:联合主键 + 外键约束,成绩允许为空(未考试时为NULL) CREATE TABLE sc ( sno CHAR(9), cno CHAR(4), grade DECIMAL(5,2), PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES student(sno), FOREIGN KEY (cno) REFERENCES course(cno) );逻辑说明:联合主键PRIMARY KEY (sno, cno)保证同一个学生选同一门课只能有一条记录——这是考试常考的约束设计。外键约束让数据库自己维护引用完整性,删了学生表里的记录时,如果选课表还有对应数据,MySQL会拒绝删除并报错。DECIMAL(5,2)表示最多5位数字、小数点后2位,成绩最大能存999.99,完全够用。
资料里建表章节讲到的三类完整性——实体完整性(主键)、参照完整性(外键)、用户定义完整性(非空、默认值、唯一),就是这张表上的三个约束,复习时对着看效果最好。
2.4 插入数据的两个必踩细节:日期格式和自增列
-- 插入学生,注意日期写法,MySQL 8.0 默认格式是 YYYY-MM-DD INSERT INTO student (sno, sname, ssex, sage, sdept) VALUES ('2018001', '张三', '男', 20, 'CS'); -- 插入成绩,考试常考 NULL 的语义 INSERT INTO sc (sno, cno, grade) VALUES ('2018001', 'C001', NULL);参数说明:sage列用INT存年龄没问题,但如果是出生日期,应该用DATE类型。资料里如果出现“把年龄算出来”的题目,通常是用YEAR(NOW()) - YEAR(birthdate)这种函数,而不是直接存年龄——这一点选择题特别喜欢考。NULL在SQL里表示“不知道、不适用、还未发生”,不是0,也不是空字符串。统计平均成绩时AVG(grade)会自动忽略NULL行,如果考到“选课但没考试的学生算不算分母”,答案是:不算。
3. 吃透SQL四大类操作:资料里的语法,只有亲手敲过才算真会
3.1 查询语句是半壁江山:SELECT的完整执行顺序
期末考试中,查询题通常占40%到50%的分数。很多同学背了SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY、LIMIT的语法顺序,但一写多表查询就乱套。核心原因是:没搞懂SQL语句的书写顺序和内部执行顺序是两回事。
-- 典型的分组查询:统计每个系的学生人数,只显示人数超过2的系 SELECT sdept, COUNT(*) AS cnt FROM student WHERE sage > 18 GROUP BY sdept HAVING COUNT(*) > 2 ORDER BY cnt DESC LIMIT 3;执行逻辑拆开看:FROM先定位表,WHERE过滤掉不满足条件的行(比如只看年龄大于18的),GROUP BY把剩下的行按系分组,HAVING对分组后的结果再过滤(组的数量大于2才保留),SELECT计算并投影出最终列,ORDER BY排序,LIMIT截断行数。
这个顺序里有三个高频考点。第一,WHERE里不能用聚合函数,比如WHERE COUNT(*) > 2是错的,因为聚合发生在WHERE之后;第二,HAVING可以引用SELECT里的别名,WHERE不行;第三,LIMIT是MySQL独有的语法,标准SQL里是FETCH FIRST n ROWS ONLY,如果资料里对比了Oracle或SQL Server,这就是出题点。
3.2 连接查询的两种写法:隐式内连接与显式JOIN
多表查询是另一座大山。资料里一定会讲等值连接、自然连接、外连接,但考场上最常翻车的,是不知道什么时候用LEFT JOIN、什么时候用普通连接。
-- 查询每门课的选课人数,没人选课的课也要显示(课程在左,选课在右) SELECT c.cno, c.cname, COUNT(s.sno) AS select_cnt FROM course c LEFT JOIN sc s ON c.cno = s.cno GROUP BY c.cno, c.cname;这里的关键是COUNT(s.sno)而不是COUNT(*)。用COUNT(*)会把左表里没匹配上右表的行也算进去——没选课的课程会显示人数1,这就是典型的逻辑错误。用COUNT(s.sno)只统计非NULL的学号,结果才是0。这个细节,资料里往往只用一句话带过,但实操中十有八九会踩。
-- 自连接:查询课程的先修课的先修课(course 表自己连自己两次) SELECT c1.cname AS course_name, c2.cname AS pre_course, c3.cname AS pre_pre_course FROM course c1 LEFT JOIN course c2 ON c1.cpno = c2.cno LEFT JOIN course c3 ON c2.cpno = c3.cno;自连接第一次看会觉得绕,但它是“同一张表存了上下级关系”这类题的标准解法。资料里如果考到“查询选修了张三同学所选全部课程的学生”,本质也是用自连接或NOT EXISTS子查询,这两种写法建议都练一遍。
3.3 修改和删除:UPDATE、DELETE用之前,先做一件保命的事
-- 把CS系所有学生的年龄加1(注意:WHERE条件不能丢) UPDATE student SET sage = sage + 1 WHERE sdept = 'CS'; -- 删除没选任何课的学生(子查询先算出来,再删除) DELETE FROM student WHERE sno NOT IN (SELECT sno FROM sc);如果漏掉WHERE,UPDATE和DELETE会作用到整张表,这个后果考试不会发生,但实操中极其致命。我在练习时养成的习惯是:先写SELECT * FROM ... WHERE ...确认命中哪些行,再把SELECT *换成UPDATE ... SET或DELETE执行。这是一个成本几乎为零但能避免大事故的好习惯。
顺带说一个高频判断题:DELETE删除数据后,自增列计数不会重置;如果用TRUNCATE TABLE,自增列会从1重新开始,而且TRUNCATE不能加WHERE条件。这两个的区别,资料里几乎必考。
3.4 存储过程:把逻辑封装进数据库
MySQL的存储过程在期末考里通常以“创建”和“调用”两种形式出现。它的价值是:把一段复杂的SQL逻辑打包成一个名字,反复调用。很多同学觉得存储过程没用,但在“应用”这个维度上,它是数据库封装能力的直接体现。
-- 创建存储过程:根据系别返回学生人数 DELIMITER // CREATE PROCEDURE count_student_by_dept(IN dept_name VARCHAR(20), OUT total INT) BEGIN SELECT COUNT(*) INTO total FROM student WHERE sdept = dept_name; END // DELIMITER ; -- 调用:in参数传入'CS',out参数用@total接收结果 SET @total = 0; CALL count_student_by_dept('CS', @total); SELECT @total;参数说明:IN表示输入参数,OUT表示输出参数。DELIMITER //是把语句分隔符临时改成双斜杠,否则存储过程体内的分号会被MySQL当成SQL语句的结束符,导致创建失败。调用结束后用SET @total = 0先初始化一个会话变量,CALL执行后@total里就是返回值。考存储过程的书写格式时,DELIMITER是默认考点,漏掉必挂。
4. 原理题不是靠背的:事务、索引、存储引擎,用三个场景理解
4.1 事务的ACID和隔离级别:自己开两个终端演一遍
MySQL原理部分的分值分布通常是:事务与并发控制、索引与B+树、范式、ER模型。其中事务隔离级别是选择题和简答题的重灾区。资料里会给出四种隔离级别的定义,但定义背得再熟,遇到“哪种隔离级别下发生哪种并发问题”的题还是会犹豫。
这个问题我的解法很笨但有效:开两个MySQL终端窗口,模拟两个并发事务。
-- 终端A:开启事务,修改数据但不提交 START TRANSACTION; UPDATE sc SET grade = 99 WHERE sno = '2018001' AND cno = 'C001'; -- 终端B:在另一个连接里查同一条数据(默认隔离级别下看不到未提交的修改) SELECT grade FROM sc WHERE sno = '2018001' AND cno = 'C001';逻辑说明:MySQL默认隔离级别是REPEATABLE READ,终端B在事务外查询,读到的是修改前的值,因为终端A还没COMMIT。如果把终端A改成SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED再开启事务,终端B立刻能看到修改后的值,这就是“脏读”的来源。
四种隔离级别和三种并发异常对应关系,用一张表记:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED | 可能 | 可能 | 可能 |
| READ COMMITTED | 不会 | 可能 | 可能 |
| REPEATABLE READ(MySQL默认) | 不会 | 不会 | 可能(InnoDB间隙锁可避免) |
| SERIALIZABLE | 不会 | 不会 | 不会 |
注意表格里括号的注释:MySQL的REPEATABLE READ通过间隙锁机制,在大多数场景下连幻读都能挡住,这和标准的SQL定义不完全一样。如果资料里只说“REPEATABLE READ存在幻读问题”,你可以在简答题里补充一句“MySQL的InnoDB通过间隙锁在快照读场景下解决了这个问题”,这属于超出教材的加分表述。
4.2 索引为什么用B+树:三个理由
“为什么索引用B+树而不是B树、红黑树、哈希表”是原理高频题。一个能拿满分的回答需要包含三层:
第一层:减少磁盘IO次数。B+树的非叶子节点只存索引键和指针,不存数据,所以每个节点能容纳更多键,树的高度更低。MySQL的页大小默认16KB,三层B+树大约能支撑千万级别数据量的查询,相当于三次磁盘IO。红黑树的树高在数据量大时明显更高,磁盘IO次数更多,这在机械硬盘时代是灾难性的。
第二层:范围查询友好。B+树的叶子节点通过指针串成了有序链表,执行WHERE grade BETWEEN 60 AND 90时,找到下界后沿着链表往后扫就行。B树的叶子节点之间没有指针连接,范围查询需要反复回溯父节点,效率差一个量级。
第三层:数据稳定性。B+树的所有数据都在叶子节点,非叶子节点不用存储记录,这样单次查询的路径长度稳定,磁盘IO波动小。哈希索引做等值查询极快,但做范围查询要全表扫描,所以InnoDB在辅助索引上不用哈希,只在内存层面用自适应哈希索引做优化。
实操里的对应原则是:区分度低的列(比如性别)不适合建索引,频繁更新的列不适合建索引,最左前缀原则决定了联合索引的列顺序。资料里如果给了EXPLAIN的输出,关注type字段从const到ALL的退化过程——ALL就是全表扫描,这是SQL调优的核心信号。
4.3 存储引擎的选型逻辑:InnoDB为何一家独大
MyISAM和InnoDB的对比是必考题。MyISAM不支持事务、不支持外键、表级锁,但查询快、占用空间小;InnoDB支持事务、行级锁、外键、崩溃恢复。资料里往往用表格对比,但更好的理解方式是问一句:为什么现在InnoDB是默认?
答案集中在“并发”和“安全”两个词上。MyISAM的表级锁意味着:读和写互斥,在写操作频繁的场景下,读请求会被阻塞;InnoDB的行级锁只锁住涉及的行,读操作默认走非锁定读,MVCC让读写可以并行。数据安全上,InnoDB的redo log让崩溃后可以恢复已提交事务,MyISAM没有这个能力,“掉电丢数据”是它的历史痛点。
在复习资料背到存储引擎时,建议顺手在MySQL里验证一次:
-- 查看两张表的存储引擎 SHOW TABLE STATUS WHERE Name = 'student'; -- 查看当前会话的隔离级别 SELECT @@transaction_isolation;第一次用SHOW TABLE STATUS看字段时可能会觉得信息太杂,重点关注Engine和Row_format两列就够了。把这条命令跑一遍,你对InnoDB的认知会从“背过的知识点”变成“见过的事实”。
5. 避坑指南:期末复习MySQL时最常见的5个“翻车”现场
5.1 现象:启动服务时提示ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'
原因:本地没装MySQL,或MySQL服务没启动,但学生习惯性地以为命令错了。还有一种情况是按Windows教程装完后,在macOS/Linux上执行mysql -uroot -p,系统找不到socket文件,因为服务没有运行。
解决:如果用docker学习,检查docker ps看容器是否在运行,容器退出后用docker start mysql8拉起;如果本机装了MySQL,先启动服务,在macOS上是brew services start mysql,在systemd的Linux发行版上是systemctl start mysqld。这类“服务没起”的问题,在考场上不会遇到,但练习时特别磨人心态。
5.2 现象:插入中文后乱码,或者建库时报“Unknown character set: 'utf8mb3'”
原因:字符集不一致。客户端连接用的字符集、数据库默认字符集、表的字符集三者不统一,最常见的是表用了utf8mb3(也就是MySQL的utf8),存不了emoji,而客户端JDBC连接串里写了useUnicode=true&characterEncoding=utf8mb4。
解决:建库时显式指定DEFAULT CHARACTER SET utf8mb4,建表时同理;连接串里写的characterEncoding统一用utf8mb4。MySQL 8.0的默认字符集已经是utf8mb4,如果你是5.7,务必在建库语句里补上这一行。这个坑在“数据库课程设计”提交作业时出现率极高。
5.3 现象:写了GROUP BY但查询报错:Expression #1 of SELECT list is not in GROUP BY clause
原因:MySQL 8.0默认开启了ONLY_FULL_GROUP_BY模式,SELECT中的非聚合列必须出现在GROUP BY里。很多资料里的旧代码是5.6时代写的,那时候这个模式默认关闭,SELECT sname, COUNT(*) FROM student GROUP BY sdept能跑通,8.0里直接报错。
解决:两条路。其一,把SELECT里的非聚合列全部加到GROUP BY后面;其二,用ANY_VALUE(sname)包一下,但这不是好习惯,因为返回哪一行不确定。正确写法是按业务需求决定——如果确实要查“每个系年龄最大的学生的姓名和年龄”,应该用窗口函数或子查询,而不是绕过ONLY_FULL_GROUP_BY。
5.4 现象:输入密码时提示Access denied for user 'root'@'localhost',但密码明明是对的
原因:常见于刚装完MySQL的时候,5.7默认安装会生成临时密码放在日志里,8.0的认证插件是caching_sha2_password,有些客户端(比如老版本Navicat)不支持这个插件,会报认证失败。
解决:如果报错信息里带caching_sha2_password字样,在MySQL里执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';,把认证插件改回旧版。但这只是为了让老客户端能连上学习环境,如果有选择余地,建议直接用支持8.0的现代客户端。别在生产环境改root的认证插件,这是血泪教训。
5.5 现象:写了子查询但结果和预期不符,查到的是空表,以为是自己数据删错了
原因:大概率是NOT IN遇到NULL了。SELECT sno FROM student WHERE sno NOT IN (SELECT sno FROM sc)这条之前写过,但如果sc表的sno列里有NULL值,NOT IN的结果会是空集——因为x NOT IN (NULL)永远不是真。这是SQL里最著名的逻辑陷阱之一,资料里提过“NULL参与比较的结果是UNKNOWN”,但没告诉你它会怎么坑人。
解决:用NOT EXISTS代替NOT IN,后者在子查询中出现NULL时不会被带偏。这条也适用于IN和EXISTS的选择,性能方面两者各自有适合场景,但逻辑正确性是第一位的。
6. 最后一招:用“30分钟自测法”验证复习效果,并在考场上少丢分
期末复习最怕的是“感觉都会,一考就废”。我自己的习惯是:考前三天,不再逐页看PDF,而是把资料翻到目录页,对着每一章的标题,在纸上默写这一章的关键内容。默写不出来的部分,用红笔圈出来,只圈不查。等整章过完后,再回头翻资料补红笔标记的部分。这个过程每次不超过30分钟,但对知识结构的暴露非常有效。
另一个实战技巧是:把所有SQL练习的报错信息收集起来,按错误码分类过一遍。ERROR 1064是语法错误,看SQL语句的拼写和逗号;ERROR 1062是主键或唯一键冲突;ERROR 1451是外键约束阻止删除。考试不会让你背错误码,但你平时排查问题的思路——先看现象、再定位原因、最后选解法——本身就是“数据库原理与应用”这门课想要培养的能力。
多说一句我自己的习惯:MySQL命令别靠复制,也别用鼠标去点可视化工具。所有建表、插入、查询语句,一律手敲。第一遍慢不要紧,第二遍开始你会发现肌肉记忆比视觉记忆可靠得多。期末考场上给你一张纸,让你手写CREATE TABLE语句时,能不打磕绊写出来的,一定是你敲过三遍以上的。
最后送你一句经验:不要把这份PDF从头到尾读完。把它当查询手册用,当习题集做,当错题本圈。带着具体问题去翻它,比通读十遍都管用。希望帮到你。
本文还有配套的精品资源,点击获取