简介该资源为《MySQL数据库基础实例教程第3版微课版》配套源代码压缩包内含书中例题、商业案例、综合实训及学校实战演练四个项目的SQL脚本与说明文件适合数据库初学者、自学者及需要提升MySQL应用能力的开发者按章节对照练习。包内共5个文件以4个sql脚本和1个txt说明文档为主整体约21KB用户可通过说明快速定位文件用途并直接导入脚本还原数据库结构、验证课堂实例与试验综合项目流程。资源由abments整理分享目前已有115人学习浏览文件小巧、目录思路清晰是一份便于快速启动的MySQL入门与实操辅助材料可结合《MySQL数据库基础实例教程第3版》一书同步使用也可作为课程设计或实训环节的参考脚本帮助读者将数据库设计、查询优化、备份恢复等知识点落到实际项目场景中。1. 拿到一份 MySQL 教材源码包先别急着解压它到底能帮你学会什么你手上这个64402-MySQL数据库基础实例教程第3版微课版-源代码含例题、案例、实训、实战四个项目.zip.zip名字已经把内容说得很清楚它不是安装包也不是某个现成的网站后台而是一套跟着课本走的 MySQL 教学源码。外层 zip 解开后往往还会再得到一个 zip很多人第一次解压后双击发现还是一堆压缩文件以为下载坏了其实这是教材配套资源常见的打包方式。这套源码解决的核心问题是“书看懂了但一开终端就卡住”。教材里的 SQL 一行行抄进命令行能跑但换到完整的建库脚本、多表查询、存储过程和工程调用时新手经常连文件先执行哪个都不知道。例题、案例、实训、实战四层结构正好是从“跟读语法”到“独立做一个数据库应用”的台阶。适合刚装好 MySQL 还想把知识落地的初学者也适合准备数据库课程设计、需要快速搭一个选题原型的在校生。我建议先不要急着把所有文件一次性导进数据库。拿到代码之后先搭一个可控的本地 MySQL 环境再按照“环境 → 目录结构 → 实战数据链路 → 排错 → 改造”的顺序推进。下面每一章都按这个路径展开最后你会得到一套能跑、能改、能给别人讲清楚的数据库实训源码。2. 搭好能跑这套源码的 MySQL 环境版本选择与最小安装配置2.1 为什么教材源码最容易卡在版本差异上MySQL 5.7 和 MySQL 8.0 在表面上都是mysql实际行为差异足以让同一段教学源码“这边能跑那边报错”。我处理过的教材配套代码里最常见的三类问题都出在版本差异上。第一是默认字符集。5.7 默认是utf88.0 默认是utf8mb4如果源码建表语句没写DEFAULT CHARSET导入 8.0 后中文宽度、排序规则都可能不一样。第二是认证插件。教材配套代码常用老式mysql_native_password但 MySQL 8.0 默认用caching_sha2_password老版本的 JDBC、PHP 或可视化工具很可能在连接阶段就直接报认证失败。第三是sql_mode尤其ONLY_FULL_GROUP_BY在 8.0 默认开启导致教材里常见的SELECT * FROM student GROUP BY class_name直接报 1055 错误。我把几个关键差异整理成了对照表导入前先对着查一遍能省掉后面大半排错时间影响点MySQL 5.7MySQL 8.0源码里的典型症状默认字符集utf8utf8mb4中文乱码、字段长度超限密码认证mysql_native_passwordcaching_sha2_password客户端报 unable to load authentication pluginGROUP BY默认不强制 ONLY_FULL_GROUP_BY默认强制ERROR 1055select 列不在 group by 中窗口函数不支持支持8.0 新语法在老版本里直接报语法错公用表表达式 WITH不支持支持解析到 WITH 处报语法错所以搭建环境的第一个原则是先确认源码面向哪个版本再去选安装方式。如果没有特别说明我会优先用 MySQL 8.0 的稳定小版本因为它仍然兼容大多数教学 SQL只有当你实测发现某段脚本用到了 5.7 专有行为、且升级改写成本太高时再切回 5.7 做对照。2.2 在 Ubuntu 上用最小命令装好 MySQL 并验证常见的教材演示环境是 Windows但服务器和面试机大多是基于 Linux。我建议至少在 Linux 上跑一遍完整安装流程这本身就是一次 MySQL 基础能力训练。如果你目前只有 Windows可以先装 WSL 再执行下面命令过程基本一致。下面是一套最小安装命令适用于 Ubuntu 22.04 或 24.04# 先更新软件索引再安装服务端与客户端 sudo apt update sudo apt install -y mysql-server mysql-client # 查看版本确认服务已经在运行 mysql --version systemctl status mysql --no-pager | head -n 5 # Ubuntu 默认 root 走 auth_socket用 sudo 进入 MySQL shell sudo mysql -u root -e SELECT VERSION();这段命令的关键点有三处。apt install -y mysql-server mysql-client会同时装上服务端和命令行客户端systemctl status mysql | head -n 5只看前几行能快速确认 active (running)最后的sudo mysql -u root是因为 Ubuntu 仓库里的 MySQL 默认 root 认证方式是auth_socket只有系统 root 或 sudo 用户才能登录直接mysql -u root -p会得到 1045 权限拒绝。如果要让后续 JDBC、Python、教材配套程序用账号密码连接需要给 root 设置一个本地密码。常见做法是ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY YourPass123; FLUSH PRIVILEGES; SELECT user, host, plugin FROM mysql.user WHERE userroot;这里把认证方式显式改成了mysql_native_password是为了兼容老教材里的连接配置。副作用是 MySQL 8.0 官方不再推荐这个插件所以如果你后续用的驱动和工具都较新可以直接写ALTER USER rootlocalhost IDENTIFIED BY YourPass123;让它走默认的caching_sha2_password更安全也更接近生产环境。2.3 用 Docker 临时起一个 5.7 环境做版本对照有些源码里的存储过程或分组查询在 MySQL 5.7 里跑得很顺放到 8.0 就报错。与其反复改本机环境不如用 Docker 起一个一次性实例端口映射到 3307避免和本机 3306 冲突。# 创建 MySQL 5.7 容器root 密码设为 root宿主机访问端口 3307 docker run --name mysql57 \ -e MYSQL_ROOT_PASSWORDroot \ -p 3307:3306 \ -d mysql:5.7 # 验证容器里的版本 mysql -h127.0.0.1 -P3307 -uroot -proot -e SELECT VERSION();参数说明--name mysql57是容器名后面用docker start/stop mysql57管理-e MYSQL_ROOT_PASSWORDroot给容器初始化 root 密码-p 3307:3306把容器内部的 3306 映射到宿主机的 3307避免与本地 MySQL 冲突。最后的连接命令里-h127.0.0.1必须写因为要走 TCP 协议而不是默认 socket。我一般会用这个容器专门验证“5.7 能跑、8.0 不能跑”的脚本。把源码里的 SQL 文件分别导进两个实例用同一套查询语句对比结果这样就不用在两个本机版本之间反复卸载安装了。环境准备好之后下一步才是真正打开源码包。3. 四层项目目录怎么消化例题、案例、实训、实战各学一遍3.1 先给源码包做“体检”解压、看目录树、找 SQL 入口拿到源码后第一件事不是双击打开而是先把它放到一个干净目录里然后再看结构。因为外层 zip 内层还套了一个 zip很多人在 Windows 上直接右键解压得到的是“文件名带中文的套娃压缩包”后面命令行操作会因为引号和编码问题变得很痛苦。在 Linux 或 WSL 下我一般这样解压# 第一层解压时指定 GBK 编码避免中文文件名乱码 unzip -O gbk 64402-MySQL数据库基础实例教程第3版微课版-源代码含例题、案例、实训、实战四个项目.zip.zip # 再解压内层 zip放到 src 目录 unzip -O gbk 64402-MySQL数据库基础实例教程第3版微课版-源代码含例题、案例、实训、实战四个项目.zip -d ./src # 只看目录不看文件确认四层结构 find ./src -maxdepth 2 -type d | sort # 列出所有 SQL 文件看看入口脚本长什么样 find ./src -name *.sql -type f | sort | head -n 20参数说明-O gbk让 unzip 用 GBK 编码解析压缩包内的中文文件名这是处理国内教材 zip 最常用的一招-d ./src指定解压目标目录find -maxdepth 2 -type d只显示两层目录够看到“例题、案例、实训、实战”四个顶层项目又不会被几百个文件刷屏。拿到目录列表后不要着急点进某个子目录。先看是否有顶层 README、建库脚本、样例数据文件。任何教学源码哪怕文件组织再乱通常都会有这几类入口create_database.sql负责建库、create_table.sql负责建表、insert_data.sql负责造样例数据剩下的就是各个章节例题和项目代码。3.2 批量导入 SQL从建库到造数的最小执行顺序很多新手拿到一包.sql文件就执行mysql 全部文件.sql结果不是报“表不存在”就是数据导进了错误的库。教材源码里建库脚本和业务脚本往往分散在四个项目目录中直接全量导入会让 MySQL 不知道该把表建到哪个库。我建议按“先建库再建表最后导数据”的顺序手动控制# 建库字符集统一指定 utf8mb4 mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS school DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 导入建表结构 mysql -uroot -p school ./src/案例/create_table.sql # 导入基础数据 mysql -uroot -p school ./src/案例/insert_data.sql # 验证核心表 mysql -uroot -p school -e SHOW TABLES;逻辑说明第一步用-e直接执行一条建库语句IF NOT EXISTS避免重复执行报错字符集写成utf8mb4基本覆盖教材业务里的中文数据。第二步和第三步用把外部 SQL 文件输入到mysql客户端并指定默认数据库school这样即使文件内部没有写USE school表也会落到正确位置。最后用SHOW TABLES确认结构导入成功。这里有一点容易忽略如果 SQL 文件内部已经写了USE xxx那么命令行里指定的school会被文件内的USE覆盖。所以我执行前会先看一眼文件头确认它有没有自带USE。如果自带我会把mysql命令行改成不带数据库名执行mysql -uroot -p ./src/案例/create_table.sql这样反而不会被默认数据库干扰。3.3 例题和案例的学习节奏先补基础再动手例题目录通常对应教材里每一章的短 SQL比如SELECT、INSERT、UPDATE、DELETE语法。这些脚本往往只有一两行夹在复杂项目代码里很容易被忽略但它们却是整个数据库增删改查的最小单元。我的建议是不要用source一次性跑完整个例题文件而是在 MySQL Workbench 或命令行里逐句执行观察影响行数和返回结果。命令行里可以用-e加-t让结果以表格形式显示mysql -uroot -p school -e SELECT student_id, name, class_name FROM student LIMIT 10;-t让输出对齐成 ASCII 表格适合看查询结果LIMIT 10避免一次返回太多行。遇到UPDATE和DELETE这类写操作我习惯先开事务再执行然后决定提交还是回滚START TRANSACTION; UPDATE account SET balance balance - 50 WHERE student_id 2023001; SELECT * FROM account WHERE student_id 2023001; ROLLBACK;这个例子背后是教材里最常见的业务账户扣款。把一整条课程源码拆成“先查再改、改完可撤销”的流程比直接执行源码里的裸UPDATE安全得多也能真正理解事务的后悔药作用。案例目录则不同它通常是章节末尾的完整场景比如学生选课、图书借阅或商品订单。案例里的 SQL 往往有多表 JOIN、外键约束和视图适合整段导入后做 EXPLAIN 分析EXPLAIN SELECT s.name, c.course_name, sc.score FROM student s JOIN score sc ON s.student_id sc.student_id JOIN course c ON c.course_id sc.course_id WHERE sc.score 60;EXPLAIN不真正执行查询而是返回 MySQL 的执行计划。读结果时重点看type、key、rows三列type从ALL变成ref或eq_ref说明 JOIN 用上了索引key显示实际用到的索引名rows是估计扫描的行数。教材案例里数据量小扫描多少行都不慢但养成看执行计划的习惯后面做实训和实战项目才不会写出“能跑但没法解释”的 SQL。4. 把实战项目跑成一条数据链路建表、造数、查询、存储过程4.1 先读懂实战项目的数据字典再碰 SQL实战项目目录和例题、案例最大的区别是它不再围绕单个知识点而是围绕一个完整业务。常见选题包括学生成绩管理、图书借阅、进销存、员工薪资等。想要把项目跑通第一件事不是执行代码而是从建表脚本里提炼出一份数据字典。数据字典不需要做得多花哨能回答四个问题就够了有哪些表、每张表存什么、表之间靠哪个字段关联、哪些字段有默认值或唯一约束。我一般用表格把 CREATE TABLE 脚本里的COMMENT、PRIMARY KEY、FOREIGN KEY手工抄出来表名核心字段类型约束关联说明studentstudent_idvarchar(20)主键被 score 引用coursecourse_idvarchar(20)主键被 score 引用scorestudent_id, course_id, scorevarchar, varchar, decimal联合主键关联 student 与 courseaccountaccount_id, balanceint, decimal默认余额为 0按业务扩展这张表对应的就是教材实战里最常见的三条核心表学生、课程、成绩。注意score表用student_id course_id做联合主键这保证同一个学生同一门课只有一条成绩记录。如果你拿到的实战项目是订单类或库存类换成“订单表、订单明细表、商品表”也是同样的套路。从源码里抄这张字典表只需要几分钟但价值很大后面写多表查询、存储过程和触发器时字段名不会记混也不会出现WHERE sc.student_id s.id这种手滑写错关联字段的隐蔽问题。4.2 从建表脚本到初始化数据再到业务查询的调试顺序实战项目的运行链路通常是建库建表 → 写基础数据 → 跑业务查询 → 通过应用层调用。很多初学者跳过了前两步直接打开某个 Java 或 Python 文件运行结果因为数据库里没有表而报 1146。正确的顺序是先让数据库侧的数据链路通再让程序侧连上来。数据库侧最小链路是这样的-- 建表 CREATE TABLE student ( student_id VARCHAR(20) PRIMARY KEY, name VARCHAR(50) NOT NULL, class_name VARCHAR(50), created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 造数据 INSERT INTO student (student_id, name, class_name) VALUES (2023001, 林晓, 计算机2301), (2023002, 张弛, 计算机2301);逻辑说明PRIMARY KEY定义主键NOT NULL约束了姓名不能为空DEFAULT CURRENT_TIMESTAMP让创建时间自动取当前时刻这是教材源码里很常见的写法。先跑建表再跑插入不用担心主键冲突或字段不存在。数据库侧数据就绪后就可以用 Python 这类脚本语言做应用侧验证。为什么用 Python因为教学实战项目里 Java 版本和 JDK 环境太容易翻车而 Python 配上 pymysql 可以最快地验证数据库连接和查询逻辑# 用 pymysql 连接实战项目数据库 import pymysql conn pymysql.connect( host127.0.0.1, port3306, userroot, passwordYourPass123, databaseschool, charsetutf8mb4, ) try: with conn.cursor() as cur: cur.execute( SELECT s.student_id, s.name, ROUND(AVG(sc.score), 2) AS avg_score FROM student s JOIN score sc ON s.student_id sc.student_id GROUP BY s.student_id, s.name HAVING AVG(sc.score) 60 ) for row in cur.fetchall(): print(row) finally: conn.close()参数说明host、port、user、password、database分别对应 MySQL 的连接地址、端口、账号、密码和默认库charsetutf8mb4必须与建库时的字符集一致否则程序里的中文可能乱码。SQL 里用JOIN关联三张表ROUND(AVG(score), 2)算平均分并保留两位小数GROUP BY按学生分组HAVING过滤出平均分低于 60 的学生。注意GROUP BY后面的字段必须和SELECT里的非聚合字段一致在 MySQL 8.0 里漏掉任何一个都会直接报 1055。4.3 存储过程和触发器先看懂调用再改参数实战项目相比案例通常会多用存储过程和触发器。存储过程把一段业务逻辑封装成“黑匣子”调用方只要传参数不需要关心内部 SQL。教材源码里的存储过程一般写在以DELIMITER开头的 SQL 文件里因为单个;会被 mysql 客户端当作语句结束必须临时把分隔符改成$$。看一个最典型的统计存储过程-- 删除同名存储过程避免重复创建报错 DROP PROCEDURE IF EXISTS get_student_count_by_class; -- 临时把分隔符改为 $$ DELIMITER $$ CREATE PROCEDURE get_student_count_by_class( IN cls VARCHAR(20), OUT cnt INT ) BEGIN SELECT COUNT(*) INTO cnt FROM student WHERE class_name cls; END$$ -- 恢复默认分隔符 DELIMITER ; -- 调用存储过程 SET cnt 0; CALL get_student_count_by_class(计算机2301, cnt); SELECT cnt;逻辑说明IN cls VARCHAR(20)是输入参数调用时传入班级名称OUT cnt INT是输出参数存储过程把统计结果写进cntSELECT COUNT(*) INTO cnt将聚合结果赋给输出变量。执行到END$$时因为分隔符是$$整个流程被当成一条完整语句而不是按行拆开执行。最后的CALL语句演示了如何传入值和取回结果。这里有个非常容易踩的坑DELIMITER $$只是 mysql 客户端的命令不是 MySQL 服务器语法。如果你在 Python 的 pymysql 或 Java 的 JDBC 里直接执行这段文本会被服务器当成语法错误。解决办法是应用侧调用存储过程时不要带DELIMITER直接执行整个CREATE PROCEDURE文本或者分成多条语句让驱动一次性提交。触发器在实战项目里通常用于审计或联动更新比如学生删除后自动清理成绩DROP TRIGGER IF EXISTS after_student_delete; DELIMITER $$ CREATE TRIGGER after_student_delete AFTER DELETE ON student FOR EACH ROW BEGIN DELETE FROM score WHERE student_id OLD.student_id; DELETE FROM account WHERE student_id OLD.student_id; END$$ DELIMITER ;这段触发器的作用是只要student表里有记录被删除就自动把该学生在score和account表中的关联记录一并清掉。AFTER DELETE ON student表示删除动作成功后触发OLD.student_id是删除前那一行的旧值MySQL 8.0 里不能用NEW.student_id取删除后的值。跑通这些存储过程和触发器后实战项目的数据链路才算真正闭合。5. 跑通源码路上的排查手册字符集、路径、权限和版本差异5.1 中文乱码与 1366先查三层字符集别急着改表现象导入 SQL 文件后SELECT查出来中文全是问号或者插入中文时报ERROR 1366 (HY000): Incorrect string value。原因MySQL 的字符集分三层服务器层、数据库层、连接层。教材源码建库时可能没写DEFAULT CHARSET或者 SQL 文件里写的是latin1而你的命令行连接默认是utf8mb4三层只要有一层不一致中文就可能出问题。解决先确认当前各层字符集再统一入口SHOW VARIABLES LIKE character_set_%; SHOW VARIABLES LIKE collation_%;执行后重点看character_set_database和character_set_connection。如果数据库是latin1可以把表转换成 utf8mb4ALTER TABLE student CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;ALTER TABLE ... CONVERT TO CHARACTER SET会转换表内所有字符型列的编码。如果表里已经有中文乱码数据转换只能保证以后不再加剧改不回已经损坏的内容。所以更可靠的做法是建库时显式写DEFAULT CHARACTER SET utf8mb4导入时用mysql --default-character-setutf8mb4三层统一后再谈其他。5.2 连接报 2002 或 1045是服务没起、socket 找错还是 root 权限被卡现象执行mysql -uroot -p后提示ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock或者报ERROR 1045 (28000): Access denied for user rootlocalhost。原因2002 通常是服务没启动或者客户端按默认/tmp/mysql.sock找不到 socket而 Debian/Ubuntu 的 MySQL 默认 socket 路径是/var/run/mysqld/mysqld.sock。1045 通常是密码错误或者 root 走了auth_socket你用密码登录当然进不去。解决先看服务状态再决定走 socket 还是 TCPsudo systemctl status mysql sudo systemctl start mysql # 强制走 TCP绕过 socket 路径问题 mysql -h127.0.0.1 -P3306 -uroot -p # 显式指定 socket 路径 mysql -uroot -p --socket/var/run/mysqld/mysqld.sock-h127.0.0.1 -P3306让客户端走 TCP 而不是 unix socket适合排查 socket 路径不一致--socket则直接把路径写死。如果 1045 依旧存在最稳妥的方式是从系统 root 进入后重新改认证方式ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY YourPass123; FLUSH PRIVILEGES;这条命令把 root 改成密码登录并刷新权限。注意这里的FLUSH PRIVILEGES在ALTER USER之后不是必须的但写上无害也能让连带修改的授权立刻生效。5.3 LOAD DATA 报 1290源码里的文件路径为什么一跑就翻车现象实战项目里有LOAD DATA INFILE /home/user/data.csv INTO TABLE student一执行就报ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option。原因为了安全MySQL 默认只允许从secure_file_priv指定的目录读取文件。源码里写死的路径往往是你当前电脑上的某个目录和服务器允许读取的目录不一致。解决先查允许目录然后把数据文件放进去SHOW VARIABLES LIKE secure_file_priv;如果结果是/var/lib/mysql-files/就把 csv 文件复制过去sudo cp /home/you/data.csv /var/lib/mysql-files/ mysql -uroot -p school -e LOAD DATA INFILE /var/lib/mysql-files/data.csv INTO TABLE student FIELDS TERMINATED BY ,FIELDS TERMINATED BY ,告诉 MySQL 每列之间用逗号分隔。更省事的替代方案是用LOAD DATA LOCAL INFILE它读取的是客户端本机文件不受服务端secure_file_priv限制但需要客户端连接时开启local_infileSET GLOBAL local_infile ON; LOAD DATA LOCAL INFILE /home/you/data.csv INTO TABLE student;LOAD DATA LOCAL在安全要求较高的生产环境里常被禁用所以教学项目里能改路径就别急着开全局开关。5.4 1055 与认证插件报错5.7 源码硬跑 8.0 的典型症状现象执行SELECT * FROM student GROUP BY class_name时报ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause或者程序连接时报认证插件错误。这两个问题经常同时出现在同一套教材源码上。原因MySQL 8.0 默认开了ONLY_FULL_GROUP_BY它要求SELECT里出现的非聚合列必须出现在GROUP BY里。5.7 时代的教学代码没遵守这个规则在 8.0 下自然报错。认证插件同理8.0 默认插件是caching_sha2_password旧驱动只认mysql_native_password。解决先看当前sql_mode再在当前会话临时放宽SELECT sql_mode; SET sql_mode STRICT_TRANS_TABLES;sql_mode查全局变量SET sql_mode只影响当前会话重启后恢复。这样改适合教学验证不建议直接改全局因为ONLY_FULL_GROUP_BY在真实项目里能帮你提前暴露不规范 SQL。认证插件的问题优先把 JDBC 或 pymysql 升级到新版本新驱动能识别caching_sha2_password如果确实改不了驱动再执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY YourPass123;把 root 切回旧插件仅作为兼容兜底。5.5 外键导入顺序错乱一条 SET 语句解决但别依赖它上线现象导入完整 SQL 文件时数据量不大但报ERROR 1451 (23000): Cannot add or update a child row: a foreign key constraint fails明明每一行看起来都正常。原因外键约束要求父表中的记录必须先存在。教材源码里的 INSERT 语句可能先插子表再插父表或者你把多个模块的 SQL 文件按名称排序后挨个导入顺序恰好颠倒。解决在导入前临时关闭外键检查导入后立刻恢复SET FOREIGN_KEY_CHECKS 0; SOURCE /path/to/全部数据.sql; SET FOREIGN_KEY_CHECKS 1;SET FOREIGN_KEY_CHECKS 0让 MySQL 暂不校验外键关系数据全部落库后再开回来。但要注意这个开关只是把校验延后不是修复数据。如果最终子表里有外键指向不存在的父表恢复检查后后续操作依然会报错。所以导入完必须跑一条关联校验比如SELECT COUNT(*) FROM score sc LEFT JOIN student s ON sc.student_id s.student_id WHERE s.student_id IS NULL;如果结果为 0说明外键关系完整这次的关闭操作只是绕开导入顺序问题没有造成数据损坏。6. 把这套源码改造成实训作业和面试题三个能复用的做法6.1 把例题里的固定条件改成参数化查询做成练习题教材例题里的 WHERE 条件基本是写死的比如WHERE student_id 2023001。我会把这类例题改造成带占位符的 Python 查询让使用者从终端输入条件顺便检查参数化写法cur.execute( SELECT * FROM student WHERE class_name %s AND score %s, (cls, min_score) )%s是占位符参数放在第二个参数的元组里由驱动负责转义避免拼接 SQL 带来的注入风险。改造完之后这份源码就从“跟读练习”变成“可验收的实训作业”。6.2 用 mysqldump 把实训库变成可备份、可迁移的环境与其专门找数据库同步工具不如先学会用一个标准命令完成最轻量的迁移mysqldump。我会在实战项目跑通后立刻做一次全库导出mysqldump -uroot -p school school_backup.sql mysql -uroot -p school school_backup.sql第一句导出结构加数据第二句导入到另一个实例。这一步看起来简单却能验证你配置的字符集、权限和默认库是否经得起从笔记本迁到服务器的过程。需要增量同步时再考虑基于 binlog 的主从复制但基础迁移必须先从mysqldump开始。6.3 给实战项目补一个造数存储过程验证报表逻辑教材自带数据往往只有二三十行跑聚合和排名看不出效果。我会在源码基础上补一个造数存储过程用于批量生成成绩数据然后观察窗口函数和分页查询DROP PROCEDURE IF EXISTS generate_scores; DELIMITER $$ CREATE PROCEDURE generate_scores(IN loops INT) BEGIN DECLARE i INT DEFAULT 0; WHILE i loops DO INSERT INTO score(student_id, course_id, score) VALUES ( 1 (i % 30), 1 (i % 10), ROUND(50 RAND() * 50, 0) ); SET i i 1; END WHILE; END$$ DELIMITER ; CALL generate_scores(1000);loops控制插入行数student_id和course_id用1 (i % n)在已有主键范围内循环避免外键冲突RAND() * 50生成 50 到 100 之间的随机成绩。造完数后再跑RANK()、DENSE_RANK()、LIMIT分页就能看出数据量对查询结果的影响。我自己的习惯是每拿到一套教学源码先按“环境、目录、链路、排错、改造”走完一遍然后删库重来一次。第二次不查笔记也能独立跑通这份源码才算真正变成了你的能力。希望帮到你。本文还有配套的精品资源点击获取
