资讯动态

MySQL课程文件实战指南:从导入到查询优化的完整流程

发布时间:2026/10/27 2:17:58 来源:尧图企业网站定制
简介这份资源是 Code With Mosh 出品的 MySQL 课程配套材料面向希望系统掌握 SQL 与关系型数据库操作的初学者和进阶开发者重点解决建库建表、约束设计、数据类型选择以及增删改查与查询优化等实际问题。压缩包共 9 个文件约 4.97MB以 5 个 PDF 和 3 个 SQL 脚本为主另有 1 个嵌套压缩包PDF 涵盖逻辑模型、性能最佳实践与项目案例说明SQL 脚本则提供建库建表及数据加载的现成示例便于边学边练。目前已有 511 人学习。资源中包含航班预订系统与视频租赁应用两个完整项目文档配合 SQL 速查表可帮助读者把表结构设计、外键关联、索引与查询性能等知识点落到真实场景中适合作为课程同步练习与项目复盘的参考材料。1. 拿到一份 MySQL 课程配套文件先别急着导入很多人学 SQL 的路径是这样的视频看完了觉得 JOIN、子查询、窗口函数都听懂了一关掉播放器面对一个空数据库连建表都卡壳。问题不在语法在于缺一套能跟着敲、能对照结果、能反复回滚的练习环境。这份 Code With Mosh 的 MySQL 课程文件包本质上就是补这个缺口的它把课程里用到的建表脚本、示例数据、练习题和答案组织成可以直接落地的文件让你从「看别人写」切换到「自己跑一遍再对答案」。适合两类人一是刚过完 SQL 基础语法、需要大量真实表结构练手的初学者二是工作里要写查询但一直靠拼凑、想系统补一遍建模和查询优化的从业者。下面按「文件怎么用 → 环境怎么搭 → 查询怎么写 → 坑在哪」的顺序拆开讲每一步都给出可复现的命令和参数。2. 课程文件的结构与导入流程从 zip 到可查询的库2.1 先看清包里有什么再决定怎么导课程配套文件通常不是单个.sql大文件而是按章节拆分的脚本集合。常见做法是解压后先列目录确认三类文件建库建表脚本create_*.sql或schema.sql、数据填充脚本insert_*.sql或data.sql、练习与答案脚本exercise_*.sql/solution_*.sql。不要一上来就source全部先看文件头部注释里的库名和字符集声明这决定了你后面连接时用哪个 database、要不要显式指定utf8mb4。# 解压并查看结构先不导入 unzip Code With Mosh - MySQL课程文件.zip -d mysql_course cd mysql_course find . -maxdepth 2 -type f -name *.sql | sort # 抽查一个脚本的头部确认库名、字符集、是否含 DROP head -n 30 ./schema.sql这段命令的逻辑是「先侦察再动手」。find的-maxdepth 2避免递归太深刷屏head -n 30看注释和CREATE DATABASE语句。参数上注意如果脚本里有DROP DATABASE IF EXISTS说明它是可重复执行的但也会清掉同名库导入前务必确认库名不是你正在用的生产库。字符集声明如果是utf8而不是utf8mb4中文和 emoji 会出问题后面建连接时要覆盖。2.2 用命令行导入比图形工具更可控图形客户端导入大脚本容易超时或静默截断命令行mysql客户端更稳。标准流程是先建库如果脚本没建再按「结构 → 数据 → 练习」顺序导入。下面以本地 MySQL 8.x 为例库名假设为course_db实际以脚本注释为准。# 1) 建库并指定字符集若脚本已含 CREATE DATABASE 可跳过 mysql -u root -p -e CREATE DATABASE IF NOT EXISTS course_db CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; # 2) 导入结构脚本--default-character-set 防止中文乱码 mysql -u root -p --default-character-setutf8mb4 course_db ./schema.sql # 3) 导入数据脚本大文件加 --max-allowed-packet 防截断 mysql -u root -p --default-character-setutf8mb4 --max-allowed-packet64M course_db ./data.sql # 4) 验证看表数量和数据行数 mysql -u root -p course_db -e SHOW TABLES; SELECT COUNT(*) FROM customers;逻辑说明第 1 步显式建库是为了控制字符集utf8mb4_0900_ai_ci是 MySQL 8 的默认排序规则大小写不敏感适合课程练习。第 2、3 步的--default-character-set是关键参数客户端和服务器字符集不一致时中文会变成问号。第 3 步的--max-allowed-packet64M针对数据脚本里可能存在的长文本或批量 INSERT默认 16M 有时不够。第 4 步的验证不要省SHOW TABLES看结构是否完整COUNT(*)看数据是否真的进去了——导入报错但退出码为 0 的情况并不少见尤其是脚本里有INSERT IGNORE时。2.3 练习脚本怎么用先跑题再看答案练习文件的价值在于「对照」。建议单独建一个练习库或加前缀表避免和示例数据混在一起。常见做法是把exercise_*.sql里的题目注释保留自己在下方写查询跑通后再打开solution_*.sql对比。对比时重点看三处JOIN 的顺序、WHERE 和 HAVING 的分工、有没有用子查询代替 JOIN。这三处最能暴露「能跑但不对」的问题。-- 示例练习「找出没有下过订单的客户」 -- 先自己写再对照答案 SELECT c.customer_id, c.first_name, c.last_name FROM customers c LEFT JOIN orders o ON c.customer_id o.customer_id WHERE o.customer_id IS NULL;这段查询的逻辑是左连接后筛空值WHERE o.customer_id IS NULL比NOT IN (SELECT ...)更安全因为后者在子查询含 NULL 时会返回空结果集——这是课程练习里高频出现的坑后面避坑章节会展开。参数上没有额外配置但要注意customers和orders的主外键列名是否和你的脚本一致课程文件不同版本列名可能有差异以DESCRIBE结果为准。3. 查询与建模的实操要点把课程示例变成自己的肌肉记忆3.1 表关系先画清楚再写 JOIN课程文件里的示例库通常是电商或 HR 场景表数量在 5 到 10 张之间关系以一对多为主。写多表查询前先跑一遍元数据查询把外键关系拉出来比凭记忆写 ON 条件可靠得多。下面这条查询从information_schema读外键不依赖图形工具。SELECT TABLE_NAME AS child_table, COLUMN_NAME AS child_col, REFERENCED_TABLE_NAME AS parent_table, REFERENCED_COLUMN_NAME AS parent_col FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA course_db AND REFERENCED_TABLE_NAME IS NOT NULL ORDER BY child_table;逻辑说明KEY_COLUMN_USAGE里REFERENCED_TABLE_NAME IS NOT NULL的行就是外键约束TABLE_SCHEMA限定当前库避免读到系统库。参数上把course_db换成你的实际库名即可。拿到这张关系表后写 JOIN 时按「驱动表 → 被驱动表」的顺序组织驱动表选过滤后行数少的那个这是后面讲执行计划时的基础。3.2 用 EXPLAIN 验证而不是靠感觉课程里讲索引的章节配套脚本往往有几十万行的示例表正好用来练EXPLAIN。写完一条查询先看type列ALL是全表扫描ref/range是走了索引index是全索引扫描比 ALL 好但通常仍不理想。再看rows估算行数和Extra里的Using filesort、Using temporary这两个出现时说明排序或分组没走索引。EXPLAIN ANALYZE SELECT c.customer_id, COUNT(o.order_id) AS order_cnt FROM customers c JOIN orders o ON c.customer_id o.customer_id WHERE c.city Shanghai GROUP BY c.customer_id HAVING order_cnt 3;EXPLAIN ANALYZE是 MySQL 8.0.18 之后才有的会实际执行并给出真实耗时比传统EXPLAIN的估算更可信。逻辑上注意HAVING用的是别名order_cntMySQL 允许在 HAVING 里引用 SELECT 别名但 WHERE 里不行——这个区别在课程练习里经常被拿来出题。参数上如果表数据量小优化器可能选全表扫描别急着加索引先用ANALYZE TABLE更新统计信息再判断。3.3 窗口函数课程里最容易被跳过的一节很多 SQL 课程把窗口函数放在最后学员容易一带而过但实际工作里排名、累计、同比都靠它。课程文件里如果有ROW_NUMBER/RANK/SUM() OVER的示例建议自己改条件重跑比如把「按部门排名」改成「按部门内按入职时间排名」观察PARTITION BY和ORDER BY换位置后的结果差异。SELECT employee_id, department_id, salary, RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_rank, SUM(salary) OVER (PARTITION BY department_id) AS dept_total FROM employees;逻辑说明PARTITION BY department_id把数据按部门分组ORDER BY salary DESC决定排名方向RANK()遇到并列会跳号1,1,3要连续排名用DENSE_RANK()。第二个窗口SUM(salary) OVER (PARTITION BY department_id)不带 ORDER BY算的是部门总额如果加上 ORDER BY就变成累计求和这是窗口函数最容易被误解的地方。参数上没有额外配置但要注意 MySQL 8 之前不支持窗口函数课程文件如果标注了版本要求别在 5.7 上硬跑。4. 避坑与排查导入和查询阶段最常见的五类翻车4.1 导入报「Unknown character set」或中文变问号现象source脚本时中断提示Unknown character set: utf8mb4或者导入成功但中文显示为???。原因有两个一是服务器版本较老不支持utf8mb4的某些排序规则二是客户端连接字符集没对齐脚本里写的是utf8mb4客户端默认latin1。解决先SELECT VERSION();确认版本8.x 一般没问题连接时统一加--default-character-setutf8mb4并在脚本头部确认SET NAMES utf8mb4;。如果已经导入乱码别在原表上改重新建库导入更干净。4.2 外键约束导致导入顺序失败现象导入数据脚本时报Cannot add or update a child row: a foreign key constraint fails。原因数据脚本的 INSERT 顺序和表依赖顺序不一致子表数据先于父表插入。解决临时关闭外键检查再导入导入后重新开启但要注意这只适合练习环境。SET FOREIGN_KEY_CHECKS 0; -- 此处执行数据导入 SET FOREIGN_KEY_CHECKS 1;关闭期间不会校验引用完整性所以导入完成后要跑一遍孤儿数据检查比如SELECT COUNT(*) FROM orders o LEFT JOIN customers c ON o.customer_id c.customer_id WHERE c.customer_id IS NULL;结果为 0 才说明数据干净。4.3 NOT IN 子查询返回空结果现象WHERE id NOT IN (SELECT customer_id FROM orders)明明有数据却返回空集。原因子查询结果里含 NULLNOT IN与 NULL 比较的结果是 UNKNOWN整个条件不成立。解决改用NOT EXISTS或左连接筛空或者在子查询里加WHERE customer_id IS NOT NULL。这是课程练习里最经典的陷阱之一答案脚本通常用NOT EXISTS自己写的时候要留意。4.4 GROUP BY 与 ONLY_FULL_GROUP_BY 冲突现象查询报Expression #N of SELECT list is not in GROUP BY clause and contains nonaggregated column。原因MySQL 5.7 之后默认开启ONLY_FULL_GROUP_BYSELECT 里非聚合列必须出现在 GROUP BY 中。解决要么补全 GROUP BY 列要么用ANY_VALUE()包住确实不需要分组的列。不建议直接关掉这个模式它帮你挡掉了很多不确定结果的查询。4.5 大脚本导入中途断开现象导入几十万行的数据脚本时连接断开报MySQL server has gone away。原因max_allowed_packet太小或者wait_timeout太短。解决导入前临时调大参数命令行加--max-allowed-packet128M服务端用SET GLOBAL max_allowed_packet134217728;。如果脚本本身可以拆分按表拆成多个文件逐个导入比调参数更稳。5. 进阶把课程库当成自己的实验田课程文件用完之后别让它躺在硬盘里。我的习惯是把它当成一个「可回滚的实验库」每次想验证一个新写法先CREATE TABLE ... LIKE复制一份示例表在副本上折腾跑完DROP掉原数据不动。这样既保留了课程数据的真实性又不用担心改坏。具体做法是先复制结构和少量数据再在副本上对比两种写法的执行计划和耗时。-- 复制结构与数据到实验表 CREATE TABLE orders_exp LIKE orders; INSERT INTO orders_exp SELECT * FROM orders LIMIT 10000; -- 对比两种写法的执行计划 EXPLAIN ANALYZE SELECT * FROM orders_exp WHERE customer_id 42; EXPLAIN ANALYZE SELECT * FROM orders_exp WHERE customer_id 0 42;第二条查询在列上做了运算索引失效type会从ref掉到ALL这个对比比看文档直观得多。参数上LIMIT 10000控制实验表规模太大反而拖慢对比。另外课程里的答案脚本不要只对一遍就过隔一周再手写一次能写出来才算真的会。我一般会在实验库里留一张notes表记录每次踩坑的现象和解决命令下次遇到同类报错直接查表比翻聊天记录快。从那以后我每次导入任何课程或项目的 SQL 脚本都强制先head看头部、再建独立库、导入后跑一遍行数校验三步不走完不往下写查询。希望这套流程帮到你少在环境上耗时间把精力留给查询本身。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑