☰
头歌MySQL实训答案PDF:DDL/DML/查询/视图/索引/存储过程全关卡代码
2026/10/2 8:21:29 网站建设 项目流程

简介:这份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 CHARSET=utf8;

这里DEFAULT CHARSET=utf8是显式指定表级字符集。头歌的 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 Name="Tracy",DeptId=302,Salary=4300.00 WHERE id=3;

WHERE id=3是必须的,不加的话整张表都会被更新。头歌判题有时候会故意不给你WHERE条件让你自己判断,但实际工作中UPDATE不带WHERE基本等于事故。

删除操作:

DELETE FROM tb_emp WHERE Salary>3000;

同样,WHERE决定了删除范围。答案里用Salary>3000作为条件,删完之后跟了一句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_id=s2.id and s1.score>90 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 position="java"); SELECT position,salary FROM tb_salary WHERE salary > ANY(SELECT min(salary) from tb_salary where position="java"); 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 classid=367;

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,math+chinese FROM student; CREATE VIEW stu_classes AS select student.stu_id,student.name,stu_info.classes FROM student,stu_info WHERE student.stu_id=stu_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 是name,2 是age,3 是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 customerNumber=p_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_score<60 GROUP BY s_id having count(*)>=2 ) GROUP BY a.s_id,a.s_name;

先把select s_id from score where s_score<60 GROUP BY s_id having count(*)>=2单独跑,确认返回的学号列表是对的,再套外层。这样出错的时候能快速定位是子查询逻辑错了还是外层关联错了。

第三个验证技巧是对比COUNT(*)和COUNT(字段)的结果差异。头歌有些关卡的数据里故意埋了NULL值,用COUNT(*)和COUNT(字段)结果不一样。答案里两种写法都有出现,遇到统计类关卡先确认题目要的是行数还是非空值数量。

一个习惯:每次UPDATE或DELETE之前,先用同样的WHERE条件写一条SELECT COUNT(*),确认影响行数符合预期再执行。头歌环境里数据量小,删错了重新初始化就行,但实际工作中没有后悔药。从那以后我每次改数据之前都强制走一遍「先 SELECT 确认,再 UPDATE/DELETE」的流程,这个习惯帮我省了至少两次线上事故。希望帮到你。

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

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

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

立即咨询