
简介这份《头歌MySQL数据库实训答案有目录.pdf》面向正在完成头歌平台MySQL数据库实训的学生与初学者聚焦数据库定义、表结构操作及约束应用等常见关卡提供可对照的参考答案与排错思路。包内仅含1个PDF文件大小约433KB带目录便于按实验模块快速定位适合在实训过程中查阅、核对语句写法与复盘知识点。内容覆盖创建数据库和数据表、主键/外键/唯一/默认约束设置也包含查看表结构、修改表名与字段类型、增删字段、调整字段排列、删除外键以及插入和更新数据等操作答案按关卡组织便于逐条手动粘贴核对。现有18407人学习说明其在同类实训资料中具有较高参考度。读者可借助分关答案理解建库建表流程、约束设计方法和ALTER TABLE等语句的实际用法并通过目录迅速找到对应实验减少因语法细节卡关的时间。1. 目录版答案怎么用先定位关卡再对齐结果集做 MySQL 实训最憋屈的时刻不是写不出 SQL而是敲完点提交判题器回一句「结果集不匹配」你盯着屏幕看半天也说不出差在哪。这份带目录的 MySQL数据库实训答案 PDF 把建库建表、约束、ALTER TABLE、单表查询、连接、子查询、聚合函数、视图索引、存储过程按关卡顺序排好了目录能直接跳到卡住的那一关每题一段可粘贴的语句加注释省掉「翻聊天记录找上一关答案」的时间。它适合正跟着实训课推进、某一关反复报错的人也适合拿它当语法清单从头把 MySQL 的建、改、查、算过一遍。但答案只是参照物能不能通过取决于你对判题规则的理解——字段顺序、别名拼写、NULL 怎么处理、字符集对不对任何一处偏差都会让「看起来一样」的语句翻车。2. 建库建表与约束CREATE TABLE 一次通过的四个要点2.1 连接参数决定了语句在哪里执行答案里几乎每关开头都挂着一行mysql -uroot -p123123 -h127.0.0.1很多人直接跳过结果在错误的库里建表判题器自然找不到对象。这行的作用是打开一个命令行会话后续所有CREATE DATABASE、USE都在这个会话里生效。参数拆开看并不复杂参数含义实训环境里的注意点-u root登录用户名判题环境一般固定不要自行改名-p123123密码-p与密码之间不能有空格命令行明文会留在 shell 历史里-h127.0.0.1走 TCP 连本机不使用本地 socket指定后连接方式与判题侧更接近# 交互式登录密码单独输入不留在 history 里适合本地练习 mysql -u root -p -h 127.0.0.1 # 实训环境里的写法密码跟在 -p 后面中间不能空格 mysql -uroot -p123123 -h127.0.0.1 # 登录后先确认当前在哪个库避免在错误的库建表 SELECT DATABASE();上面三条命令的区别在于登录方式和执行前的位置确认。-p与密码之间加空格会把后面的字符串当成库名这是新手最容易踩的一次SELECT DATABASE()返回 NULL 说明还没进任何库此时执行CREATE TABLE会直接报 1046。我一般习惯在粘贴答案前先跑一次SHOW DATABASES;确认目标库已经存在再决定要不要保留答案里那句CREATE DATABASE。2.2 建库建表的字段顺序就是判题标准第一关、第二关那种「创建数据库再建表」的题看着最没技术含量通过率反而不高。原因很简单判题侧通常会对表执行一次结构比对列名、类型、长度、先后顺序都会参与比较。VARCHAR(32)写成VARCHAR(30)FLOAT换成DECIMAL或者把deptId挪到name前面结果集可能完全一样但结构校验直接不通过。-- 第一关建库。库名大小写要和题目给的一致 CREATE DATABASE MyDb; -- 第二关建表前必须先切库否则表会落到当前默认库里 USE MyDb; CREATE TABLE t_emp ( id INT, name VARCHAR(32), deptId INT, salary FLOAT );这里的关键是「先USE再建表」。很多答案片段只给了CREATE TABLE如果上一关结束后会话还停在别的库表就建歪了。字段类型的选择也有讲究INT存员工编号够用VARCHAR(32)给姓名留了冗余FLOAT存工资在实训场景没问题真做金额计算建议换DECIMAL(10,2)浮点累加会出现2300.0000000001这种尾巴。另外提醒一句MySQL 8.0.17 之后整型的显示宽度如INT(11)已被标记为废弃SHOW CREATE TABLE里看不到它但老版本实训环境仍按带宽度解析粘贴答案时保持原样最稳。2.3 主键、复合主键与外键三种约束的写法差异第三关考主键题目往往要求建两张表一张单列主键一张复合主键。这两张表的差别不在数据而在约束定义的位置——单列主键可以直接写在列后面复合主键必须写成表级约束。USE MyDb; -- 单列主键约束写在列定义后面 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) );复合主键的语义是「姓名 电话」这个组合不能重复但同名的两个人只要电话不同就能同时存在同一个电话挂在不同姓名下也没问题。判题器一般会插入两条冲突数据看是否报 1062所以约束名和列顺序都不能随意调整。外键那关的坑集中在建表顺序上。t_student.classId引用t_class.id父表必须先存在否则报 1824被引用的列必须是索引列主键自带索引两张表的存储引擎都得是 InnoDB字符集也要一致否则可能报 3780。USE MyDb; -- 父表先建id 作为被引用列必须是主键或唯一索引 CREATE TABLE t_class ( id INT PRIMARY KEY, name VARCHAR(22) ); -- 子表后建CONSTRAINT 后面是外键名删外键时要靠它 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这段不是可选项它给外键起了名字后面DROP FOREIGN KEY用的就是这个名字而不是列名。省掉CONSTRAINT时 MySQL 会自动生成一个t_student_ibfk_1之类的名字靠猜去删基本删不掉。注意部分答案文本里t_class建表语句结尾多了一个右括号直接整段粘贴会报 1064 语法错误。遇到这种排版残留先看括号是否成对再执行。2.4 唯一、默认值、自增与字符集一行表定义里的四个属性第五关「添加常用约束」把PRIMARY KEY、AUTO_INCREMENT、NOT NULL、UNIQUE、DEFAULT塞进了一张表是最容易漏写属性的一关。CREATE DATABASE MyDb; USE MyDb; CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, -- 自增必须配合索引使用 username VARCHAR(32) NOT NULL UNIQUE, -- 非空 唯一会额外生成唯一索引 sex VARCHAR(4) DEFAULT 男 -- 不插值时自动填充 ) DEFAULT CHARSET utf8;四个属性各自的作用AUTO_INCREMENT让id在插入时自动递增前提是该列已经是索引列否则报 1075NOT NULL保证username不允许空值UNIQUE会隐式创建一个唯一索引重复插入报 1062DEFAULT 男在INSERT省略该列时生效。表级DEFAULT CHARSET utf8决定了中文默认值能不能存进去utf8是三个字节的旧实现能存常用汉字但存不了四字节字符部分生僻字和 emoji新项目一律用utf8mb4。实训环境如果按utf8校验改成utf8mb4反而可能被判结构不一致这一项以题目给的为准。2.5 ALTER TABLE 的五个动作改名、改列、增删、挪位、删外键结构变更那几关把ALTER TABLE的常用形态几乎考全了动作看着零碎其实只有五个改表名、改列名和类型、加列、删列、调整列位置外加一个删外键。USE Company; -- 1. 改表名RENAME 后面直接跟新表名TO 可省略 ALTER TABLE tb_emp RENAME TO jd_emp; SHOW TABLES; DESCRIBE jd_emp; -- 2. 改列名 类型用 CHANGE只改类型用 MODIFY ALTER TABLE tb_emp CHANGE Id prod_id INT(11); ALTER TABLE tb_emp MODIFY Name VARCHAR(30); DESCRIBE tb_emp;CHANGE必须把旧列名、新列名、新类型完整写一遍少一个参数就报语法错MODIFY只改类型或属性列名不动。真正需要警惕的是这两个关键字都会重写整个列定义原来写了NOT NULL、DEFAULT、COMMENT的列重写时没带上就全丢了。MySQL 8.0 提供了RENAME COLUMN 旧名 TO 新名只改名字不动类型做单纯改名时更安全。-- 3. 加列并指定位置删列直接 DROP ALTER TABLE tb_emp ADD Country VARCHAR(20) AFTER Name; ALTER TABLE tb_emp DROP Salary; DESCRIBE tb_emp; -- 4. 调整列位置FIRST 挪到首列AFTER 挪到指定列后面 ALTER TABLE tb_emp MODIFY Name VARCHAR(25) FIRST; ALTER TABLE tb_emp MODIFY DeptId INT(11) AFTER Salary; DESCRIBE tb_emp;AFTER Name表示新列插在Name后面FIRST表示放到第一列不写这两个关键字就默认追加到末尾。位置在判题里是硬指标DESCRIBE输出的顺序和期望不一致即使列全对也不算过。DROP Salary会连同该列上的索引、默认值一起删掉如果这一列还被视图或外键引用会直接报 1828。-- 5. 删外键DROP FOREIGN KEY 后面跟的是约束名不是列名 ALTER TABLE tb_emp DROP FOREIGN KEY emp_dept; -- 用 \G 竖排查看建表语句确认外键和索引是否清干净 SHOW CREATE TABLE tb_emp \G\G是命令行客户端的结束符变体把结果按「列名: 值」竖着打印宽表看起来清爽很多。删完外键别急着走SHOW INDEX FROM tb_emp;再看一眼——建外键时 MySQL 会自动在同名列上建一个普通索引5.7 里删外键后这个索引通常还在需要额外ALTER TABLE tb_emp DROP INDEX emp_dept;才能彻底清理8.0 的部分版本会连带删除具体以SHOW INDEX的实际输出为准别凭记忆判断。3. 数据写入与单表查询从三条 DML 到 WHERE 的六种条件3.1 INSERT、UPDATE、DELETE 的边界条件数据操作那三关的答案本身很短翻车点全在边界上。批量插入要注意列名列表和值的顺序一一对应字符串用单引号日期和数字不加引号。USE Company; -- 多行插入列名列表决定值的对应关系不是表定义顺序 INSERT INTO tb_emp (Id, Name, DeptId, Salary) VALUES (1, Nancy, 301, 2300.00), (2, Tod, 303, 5600.00), (3, Carly, 301, 3200.00); SELECT * FROM tb_emp;INSERT INTO 表(列...) VALUES (...)这种写法里列的顺序可以任意只要和值对齐就行如果省略列名列表就必须按建表时的完整列顺序给全所有值。字符串用双引号在默认模式下也能跑但开了ANSI_QUOTES之后双引号会被当成标识符跨环境迁移容易翻车统一用单引号最稳。-- 更新WHERE 锁定的行数必须和题目要求一致 UPDATE tb_emp SET Name Tracy, DeptId 302, Salary 4300.00 WHERE id 3; SELECT * FROM tb_emp; -- 删除注意边界是 还是 差一个等号结果就不同 DELETE FROM tb_emp WHERE Salary 3000; SELECT * FROM tb_emp;UPDATE不写WHERE会更新全表MySQL 默认没开安全更新模式不会拦你执行完只能靠备份回滚。DELETE那关的判分点经常落在和上Salary 3000保留 3000 整的那行 3000则删掉题目描述里的「超过」和「不低于」是两个意思。另外DELETE是逐行删除并写日志TRUNCATE是重建表、自增值归零、不能带WHERE两者在实训里经常被混用。3.2 IN、BETWEEN、LIKE、IS NULL、DISTINCT 各管一段单表查询一到三基本是在把WHERE子句的关键字挨个过一遍每个关键字都有自己的语义边界。USE Company; -- IN等值列表NOT IN 遇到 NULL 会返回空集 SELECT Name, Salary FROM tb_emp WHERE Id NOT IN (1); -- BETWEEN AND闭区间包含两端 SELECT Name, Salary FROM tb_emp WHERE Salary BETWEEN 3000 AND 5000; -- LIKE% 匹配任意长度_ 匹配单个字符 SELECT Name, Salary FROM tb_emp WHERE Name LIKE C%; -- IS NULL判断空值不能写成 NULL SELECT * FROM tb_emp WHERE DeptId IS NULL; -- DISTINCT作用于整行结果不是单个列 SELECT DISTINCT Name FROM tb_emp;NOT IN的子查询或列表里只要出现一个 NULL整个条件就恒为 UNKNOWN结果集为空这个坑在线上排查时能耗掉半天。BETWEEN 3000 AND 5000等价于 3000 AND 5000边界值会被包含。LIKE C%里的%是通配符C本身大小写是否敏感取决于列的排序规则utf8_general_ci下不区分utf8_bin下区分。 NULL永远不成立必须写IS NULL。DISTINCT去重的是整行组合SELECT DISTINCT Name, Salary是「姓名工资」整体去重不是只对姓名去重。3.3 AND/OR 优先级、ORDER BY 与 LIMIT 分页多条件查询那关最容易忽略的是运算符优先级AND高于OR不加括号的A OR B AND C会被解析成A OR (B AND C)和直觉相反。-- AND 优先于 OR混用时必须加括号 SELECT * FROM tb_emp WHERE DeptId 301 AND Salary 3000; SELECT * FROM tb_emp WHERE DeptId 301 OR DeptId 303; -- 排序DESC 降序默认 ASC 升序 SELECT * FROM tb_score WHERE class_id 1 ORDER BY score DESC; -- LIMIT offset, countoffset 从 0 开始跳过 1 行取 4 行 SELECT * FROM tb_score ORDER BY score DESC LIMIT 1, 4;LIMIT 1, 4取的是排序后的第 2 到第 5 条offset从 0 计数这点和人的直觉差一位题目问「第 2 名到第 5 名」时正好对应这个写法。只写一个数字LIMIT 4表示取前 4 条等价于LIMIT 0, 4。深分页的性能问题在实训里不会暴露但值得记一笔LIMIT 100000, 10会让存储引擎扫描并丢弃前十万行常见做法是用主键游标替代偏移量。USE Products; -- 用子查询先定位边界主键外层按主键范围取数避免大偏移扫描 SELECT prod_id FROM products WHERE prod_id ( SELECT prod_id FROM products ORDER BY prod_id LIMIT 4, 1 ) ORDER BY prod_id p a hrefhttps://download.csdn.net/download/Gzzzww/86745104 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p