简介这份PDF资料面向正在学习MySQL数据库课程的高校学生与自学者针对头歌平台实训作业中卡壳、需要对照答案复盘的场景提供了一份带目录的完整参考答案。资源包内仅1个PDF文件约433KB按实训关卡组织内容目录清晰便于快速定位到具体关卡。内容覆盖数据库定义与操作、主键与外键约束、唯一约束、查看表结构、修改表名与字段、增删字段、调整字段排列位置、删除外键约束以及插入与更新数据等实训任务每关均给出可直接参考的SQL语句与执行思路方便读者对照自己的写法排查语法与逻辑问题。目前已有18353人学习下载适合需要系统梳理MySQL基础操作、查漏补缺的初学者也可作为课程复习时的速查清单。1. 头歌 MySQL 实训答案 PDF一份能直接抄作业的实战代码库做头歌 MySQL 实训的时候最让人抓狂的不是 SQL 本身而是关卡环境里那些看不见摸不着的约束——表名大小写、字段顺序、默认字符集任何一个对不上就是满屏红字。这份「头歌 MySQL 数据库实训答案有目录.pdf」把数据库定义、表操作、约束、单表查询、连接查询、子查询、聚合函数、视图、索引、存储过程这些关卡的参考代码全部整理成了带目录的文档每一关对应一段可直接粘贴的 SQL。它解决的核心问题很具体让你在头歌实践教学环境里快速定位当前关卡该写什么而不是对着报错反复试。适合正在刷头歌 MySQL 实训的学生也适合想拿这套题当 MySQL 语法练习册的初学者。PDF 带目录意味着你不需要从头翻到尾直接跳到对应关卡就行。2. 从建库到约束把 DDL 语句拆开看参数2.1 建库建表为什么总在字符集上翻车头歌第一关通常就是创建数据库和表。答案里给的create database MyDb;看起来简单但实际环境里如果你不指定字符集后续插入中文数据就可能出现乱码。答案中有一段值得注意的写法CREATE TABLE t_user( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32) NOT NULL UNIQUE, sex VARCHAR(4) DEFAULT 男 ) DEFAULT CHARSETutf8;这里DEFAULT CHARSETutf8是显式指定表级字符集。头歌的 MySQL 版本通常是 5.7默认字符集可能是 latin1不指定的话VARCHAR字段存中文会出问题。AUTO_INCREMENT让 id 自动递增NOT NULL UNIQUE组合保证用户名既不能为空也不能重复DEFAULT 男给性别字段兜底。这三个约束叠在一起是实际业务表里最常见的写法。参数上要注意VARCHAR(32)里的 32 是字符数不是字节数utf8 下中文占 3 字节所以 32 能存 32 个中文字符。INT后面的(11)在 MySQL 8.0 里已经废弃显示宽度但头歌环境如果是 5.7 仍然接受这种写法不影响功能。2.2 主键、外键、唯一约束的写法差异答案里主键约束有两种写法值得对比。单列主键直接跟在字段后面create table t_user1( userId INT PRIMARY KEY, name VARCHAR(32), password VARCHAR(11), phone VARCHAR(11), email VARCHAR(32) );复合主键则要单独声明create table t_user2( name VARCHAR(32), phone VARCHAR(11), email VARCHAR(32), PRIMARY KEY(name,phone) );复合主键的含义是 name 和 phone 的组合不能重复单独一个字段可以重复。这个在头歌的判题逻辑里很关键——如果你把复合主键写成两个单独的 PRIMARY KEY直接报错。外键约束的写法在答案里是这样的CREATE TABLE t_student( id INT PRIMARY KEY, name VARCHAR(22), classId int, CONSTRAINT fk_stu_class1 FOREIGN KEY(classId) REFERENCES t_class(id) );CONSTRAINT fk_stu_class1给外键起了个名字方便后续用ALTER TABLE ... DROP FOREIGN KEY fk_stu_class1删除。不起名字的话 MySQL 会自动生成一个但删除时你得先去查SHOW CREATE TABLE看自动生成的名字是什么多一步操作。我一般会强制自己起名字后面改表结构的时候省事。注意头歌环境里外键关联的父表必须先存在否则REFERENCES t_class(id)会直接报 1215 错误。答案里先CREATE TABLE t_class再CREATE TABLE t_student的顺序不能反。3. 表结构修改与数据操作ALTER 和 DML 的实战细节3.1 ALTER TABLE 改字段的四种操作头歌「数据库和表的基本操作」这一组关卡集中练了ALTER TABLE的几种用法。答案里对应的代码分别是改表名ALTER TABLE tb_emp RENAME jd_emp;改字段名和类型ALTER TABLE tb_emp CHANGE Id prod_id int(11); ALTER TABLE tb_emp MODIFY Name varchar(30);CHANGE和MODIFY的区别是CHANGE可以同时改字段名和类型MODIFY只能改类型不能改名字。答案里用CHANGE Id prod_id int(11)把Id改成了prod_id用MODIFY Name varchar(30)只改了Name的长度。头歌判题会检查最终的表结构所以改完之后通常要跟一句DESCRIBE tb_emp;确认。添加和删除字段ALTER TABLE tb_emp ADD Country varchar(20) AFTER Name; ALTER TABLE tb_emp DROP Salary;AFTER Name指定新字段插在Name后面。不写AFTER默认加到最后一列。头歌有些关卡会校验字段顺序所以AFTER不能省。调整字段位置ALTER TABLE tb_emp MODIFY Name varchar(25) FIRST; ALTER TABLE tb_emp MODIFY DeptId int(11) AFTER Salary;FIRST把字段挪到第一列AFTER Salary挪到Salary后面。这里有个坑MODIFY调整位置时必须把字段的完整类型写全只写MODIFY Name FIRST会丢失varchar(25)的定义。3.2 INSERT、UPDATE、DELETE 的参数边界数据操作部分答案给了批量插入的写法INSERT INTO tb_emp(Id,Name,DeptId,Salary) VALUES (1,Nancy,301,2300.00), (2,Tod,303,5600.00), (3,Carly,301,3200.00);批量插入比单条插入效率高头歌环境里数据量小感觉不出来但实际业务中几千条数据用批量插入能差出几十倍时间。字段列表(Id,Name,DeptId,Salary)显式指定了插入顺序这样即使表结构变了只要字段名对得上就不会插错。更新操作UPDATE tb_emp SET NameTracy,DeptId302,Salary4300.00 WHERE id3;WHERE id3是必须的不加的话整张表都会被更新。头歌判题有时候会故意不给你WHERE条件让你自己判断但实际工作中UPDATE不带WHERE基本等于事故。删除操作DELETE FROM tb_emp WHERE Salary3000;同样WHERE决定了删除范围。答案里用Salary3000作为条件删完之后跟了一句SELECT * FROM tb_emp;来验证结果。这个习惯值得保留——每次DELETE或UPDATE之后先SELECT确认影响的行数对不对。4. 查询进阶连接、子查询与聚合的踩坑记录4.1 内连接和外连接的结果集差异答案里连接查询部分给了内连接和外连接的对比写法。内连接select tb_student.name as studentName, tb_class.name as className from tb_student join tb_class on tb_class.id tb_student.class_id;外连接select tb_student.name as studentName, tb_class.name as className from tb_class right join tb_student on tb_class.id tb_student.class_id;内连接只返回两张表都能匹配上的行外连接会保留主表的所有行匹配不上的字段填NULL。答案里用right join和left join分别实现了「所有学生对应的班级」这个需求。头歌判题会检查结果集的行数和内容如果学生表里有人没有班级内连接会少几行外连接不会。复合条件连接select s1.name as studentName, score, s2.name as className from tb_student as s1, tb_class as s2 where s1.class_ids2.id and s1.score90 order by score desc;这里用了隐式连接逗号分隔表名加WHERE条件效果等同于INNER JOIN。s1和s2是表别名在多表查询里必须用别名区分同名字段。order by score desc按成绩降序排列头歌有些关卡会校验排序结果。4.2 子查询中 ANY、ALL、IN 的语义区别答案里子查询部分有一组对比SELECT position,salary FROM tb_salary WHERE salary ANY(SELECT max(salary) FROM tb_salary where positionjava); SELECT position,salary FROM tb_salary WHERE salary ANY(SELECT min(salary) from tb_salary where positionjava); select position,salary from tb_salary where position in(java); ANY表示大于子查询结果中的任意一个值等价于大于最小值。 ALL表示大于所有值等价于大于最大值。答案里第一条用 ANY(SELECT max(...))实际上等价于 max因为子查询只返回一个值。第二条用 ANY(SELECT min(...))等价于 min。IN则是等值匹配position in(java)就是position java。这里容易翻车的地方是当子查询返回多行时 ANY和 ALL的行为差异会放大。头歌有些关卡会故意让子查询返回多行来考你理解这时候不能想当然。4.3 聚合函数与 GROUP BY 的配合答案里聚合函数部分覆盖了COUNT、SUM、AVG、MAX、MIN五个函数。以COUNT为例select count(*) from tb_class; select classid,count(*) from tb_class where classid367;COUNT(*)统计所有行数包括NULL值。COUNT(字段名)会跳过NULL值。头歌判题如果数据里有NULL这两种写法的结果会不一样。GROUP BY配合HAVING的写法select gradeId,sex,count(*) from student where gradeId in (2,3,4) group by gradeId,sex;WHERE在分组前过滤HAVING在分组后过滤。答案里还有一条select sno,count(*) from tb_grade where score 90 group by sno having count(pno) 2;这条查询的是至少有两门课程在 90 分以上的学生。WHERE score 90先筛出 90 分以上的记录然后按学号分组HAVING count(pno) 2再筛出课程数大于等于 2 的学号。顺序不能反HAVING里不能用WHERE的别名。注意MySQL 的ONLY_FULL_GROUP_BY模式在 5.7 之后默认开启SELECT列表里非聚合字段必须出现在GROUP BY里。头歌环境如果报1055错误检查一下SELECT后面的字段是不是都分组了。5. 视图、索引与存储过程进阶对象的创建与验证5.1 视图的两种创建方式答案里视图部分给了单表视图和多表视图CREATE VIEW stu_view AS select math,chinese,mathchinese FROM student; CREATE VIEW stu_classes AS select student.stu_id,student.name,stu_info.classes FROM student,stu_info WHERE student.stu_idstu_info.stu_id;单表视图直接映射原表字段多表视图把两张表关联后的结果固化成一个虚拟表。视图不存数据每次查询时动态生成。头歌判题会检查视图定义是否存在有时候还会查information_schema.views来验证。创建视图的坑在于如果视图定义里用了SELECT *后续原表加字段视图不会自动更新。答案里都是显式列出字段名这个习惯更稳妥。5.2 索引的创建与查看索引部分答案给了单列索引和组合索引CREATE UNIQUE INDEX name_index ON student(name); CREATE INDEX score_index ON student(score); ALTER TABLE person ADD INDEX name_city_score (name,age,address); SHOW INDEX FROM student;UNIQUE INDEX保证索引列的值唯一INDEX是普通索引。组合索引(name,age,address)遵循最左前缀原则——查询条件里必须包含name才能用上这个索引只查age或address用不上。SHOW INDEX FROM student;用来验证索引是否创建成功。头歌判题会检查Key_name和Column_name是否匹配。组合索引的Seq_in_index字段表示列在索引中的顺序1 是name2 是age3 是address。5.3 存储过程的参数模式答案里存储过程用了一个输入参数和一个输出参数delimiter $$ create PROCEDURE GetCustomerLevel( in p_customNumber int(11), out p_customerLevel varchar(10) ) Begin declare levels int; select creditlimit into levels from customers where customerNumberp_customNumber; if levels 5000 then set p_customerLevel SILVER; elseif levels 10000 then set p_customerLevel GOLD; else set p_customerLevel PLATINUM; end if; select p_customNumber as customerNumber,p_customerLevel; End$$delimiter $$把语句结束符从分号临时改成$$这样存储过程内部的;不会被 MySQL 客户端提前截断。in参数接收外部传入的值out参数把结果传回去。declare levels int;声明局部变量select ... into levels把查询结果赋给变量。头歌判题调用存储过程时通常用CALL GetCustomerLevel(103,level); SELECT level;来验证输出参数。如果delimiter没改创建过程时会报语法错误。6. 用这套答案做自测三个验证技巧和一个习惯拿到这份 PDF 之后最有效的用法不是照着抄一遍就完事而是把它当成自测题来用。我一般会先把答案遮住自己写一遍然后跟 PDF 里的代码对比。差异往往出在三个地方字段顺序、字符集指定、WHERE条件的边界值。第一个验证技巧是善用DESCRIBE和SHOW CREATE TABLE。头歌很多关卡只检查最终表结构不关心中间过程。写完ALTER TABLE之后立刻DESCRIBE 表名;看一眼字段类型、顺序、默认值是否跟预期一致。SHOW CREATE TABLE 表名\G能看到完整的建表语句包括字符集、引擎、外键约束名比DESCRIBE更全。第二个验证技巧是分步执行查询。复杂查询不要一次性写完再运行先写子查询单独跑一遍看结果再套外层。比如答案里「查询两门课程不及格同学信息」那条select a.s_id,a.s_name,ROUND(AVG(b.s_score))avg_score from student a inner join score b on a.s_id b.s_id where a.s_id in( select s_id from score where s_score60 GROUP BY s_id having count(*)2 ) GROUP BY a.s_id,a.s_name;先把select s_id from score where s_score60 GROUP BY s_id having count(*)2单独跑确认返回的学号列表是对的再套外层。这样出错的时候能快速定位是子查询逻辑错了还是外层关联错了。第三个验证技巧是对比COUNT(*)和COUNT(字段)的结果差异。头歌有些关卡的数据里故意埋了NULL值用COUNT(*)和COUNT(字段)结果不一样。答案里两种写法都有出现遇到统计类关卡先确认题目要的是行数还是非空值数量。一个习惯每次UPDATE或DELETE之前先用同样的WHERE条件写一条SELECT COUNT(*)确认影响行数符合预期再执行。头歌环境里数据量小删错了重新初始化就行但实际工作中没有后悔药。从那以后我每次改数据之前都强制走一遍「先 SELECT 确认再 UPDATE/DELETE」的流程这个习惯帮我省了至少两次线上事故。希望帮到你。本文还有配套的精品资源点击获取