简介:面向MySQL数据库初学者的配套源代码包,围绕《MySQL数据库基础实例教程(第3版)(微课版)》设计,按例题、案例、实训、实战四个模块组织,覆盖从基础建表到综合项目开发的完整练习路径,适合自学与课堂同步使用。压缩包内共5个文件,含4个SQL脚本与1个TXT说明文档,整体仅21KB,轻量易用。SQL脚本对应书店例题、宠物商店商业案例、图书馆综合实训、学校数据库实战演练等场景,可直接导入MySQL运行,便于对照教材验证结果并通过修改参数加深理解;TXT文件对文件用途做了简要说明。四个模块由浅入深,例题部分方便逐条验证基础语法,案例与实训部分贴近真实业务需求,实战部分可练习数据库的综合设计与部署。资源目前已吸引115人学习,适合希望把书本知识转化为可运行操作的MySQL入门读者。
1. 一套 MySQL 源码包怎么用:先定位再跑通,比写 SQL 更考验环境
拿到《MySQL数据库基础实例教程(第3版)(微课版)》配套的源代码压缩包,我建议第一件事不是急着敲 SQL,而是把压缩包打开,按“例题、案例、实训、实战”四个层级把资源分开。这个包能解决三类人的同一个问题:会看书但不会动手、装好了数据库却导不进数据、想练手却找不到成套数据的学生和自学者。它最有价值的部分不是那些建表语句,而是成套的造数脚本和可对照的结果。把环境理顺,后面走一步成一步;环境不顺,第一节课就会卡在登录上。理解了它的组织方式,你才知道该先跑哪个文件,跳过哪一层,以及卡住时去检查什么。
2. 例题、案例、实训、实战:四个项目的分工与正确学习顺序
2.1 四个目录的分工:从单点到闭环
标题里已经把源码包拆成四个项目:例题、案例、实训、实战。这是很典型的高校教材分层方式。我按常见做法把它们理解成四个目录或者四组脚本,每一级的文件形态和学习目标都不一样。
例题回应的问题是“这一节在讲什么”。通常是一个知识点配一条或几条 SQL,比如一条 INSERT、一个 WHERE 条件、一个聚合函数。它的作用是把语法和返回结果绑在一起看,适合把教材里涉及的数据库增删改查逐个敲一遍。这种文件最小,有时候只有几行,但恰恰是后面所有内容的地基。
案例回应的问题是“这些知识点怎么串起来”。这一层开始出现多张表和表之间的关系,比如用户表、商品表、订单表的连接查询,还会带上外键和分组统计。它的文件量比例题大,但结构还比较清晰,考的是你能不能看懂表关系。如果你在前面跳过了例题,在这里大概率会卡在某个字段为什么对不上。
实训回应的问题是“能不能独立完成一次上机任务”。它通常是带任务要求的练习包,给出部分表和部分查询,留出缺口让你补全。跑通之后往往还要你改参数,观察结果变化。这里不再是“照着抄”,而是“理解后改”。很多初学者在这里第一次感受到 SQL 不是背出来的,是试出来的。
实战回应的问题是“能不能交付一个小型项目”。它包含建库、建表、造数、多表查询、视图或存储过程,有时候还会带一个程序连接入口。这一级的文件组织最接近真实项目的雏形,也是四个项目里唯一值得你在完整学完前三层之后再打开的部分。
解压之后第一步,先把所有非 .sql 的文件找出来,比如 .txt、.doc、.md 这类任务说明文档。它们往往比代码更重要,因为脚本只告诉你“怎么执行”,说明文档才告诉你“执行完应该看到什么”。目录结构乱一点没关系,任务说明文件齐全,这套源码就能用。
2.2 学习顺序:先用例题热身,最后才碰实战
很多人拿到源码第一件事是打开实战项目,然后被几十张表和上百条语句吓住。最大的障碍不是 SQL 难度,而是顺序放反了。例题是最小可运行的片段,先把这类脚本导入数据库,逐行执行,目的是把“语法”和“执行结果”对应起来。
我自己的固定流水线是这样:先手工敲例题,不复制粘贴,每条语句执行完看一眼结果;再把案例整包导入,用 SHOW TABLES 和 DESC 观察表结构;然后做实训,只补关键查询和修改片段,不重抄前面的建表语句;最后回头看实战,把它当综合演练,从头到尾走一遍。这个顺序和教材难度曲线一致,能明显减少半途放弃的概率。
例题阶段最忌讳的是“看懂了”就直接跳过。SQL 的“看懂”和“写出来”之间隔着一条鸿沟,手一停,后面案例里的连接查询就会露馅。案例阶段相反,不需要把每条语句都背下来,重点放在表关系上:哪张表是主表,哪张表通过外键关联,查询结果为什么会多出重复行。实训阶段先读题再动手,脚本里留的缺口往往有提示,先找到缺口再补,比盲目执行有效得多。
2.3 一张对照表:用验收标准检查卡在哪一层
| 项目类别 | 常见文件形态 | 学习目标 | 我习惯用的验收标准 |
|---|---|---|---|
| 例题 | 单条 SQL 或极小脚本片段 | 掌握单个语法或函数 | 不查书也能写出来,并能解释执行顺序 |
| 案例 | 多表结构与若干查询 | 理解表关系与连接查询 | 换一套表名能独立写出等价查询 |
| 实训 | 带任务书的脚本骨架 | 能补全并修改已有脚本 | 改掉表名或字段条件后依然跑通 |
| 实战 | 完整库脚本加应用入口 | 综合建库、造数、查询、排错 | 从零到一复现整个流程并说明每一步为什么这么做 |
这张表的价值在于,卡住的时候能快速定位问题出在哪一层。例题能看懂但案例卡住,多半是表关系没理顺,回去画一张简单的表关系图,标出主键和外键,不要硬往下学。实训卡住,多半是需求理解不到位,先做一个小规模替代表,再加条件。实战卡住,大概率是前面某一步没做透,回头找补比硬啃更有效率。
这套源码的另一个优势是每一步都有结果可对照。比漫无目的刷题稳,也比只看书踏实。使用时尽量保留原始文件不被破坏,把修改版复制备份后再改,比如把 example.sql 复制成 example_practice.sql。这样折腾坏了随时有后悔药,不影响原包。
3. 环境准备与数据导入:装 MySQL、建库、执行 .sql 的完整链路
3.1 MySQL 版本选型:5.7 省心,8.0 面向现状
装 MySQL 不是下载完就结束,版本选择直接影响源码能否导入。这类面向初学者的教程源码,字符集和语法通常偏保守,MySQL 5.7 对老脚本的兼容性最好,适合只想复现教材内容的读者。8.0 是当前主流,默认字符集已经是 utf8mb4,处理老脚本时偶尔会遇到排序规则不兼容,但作为学习和日后找工作更推荐直接上 8.0。网上 mysql 安装教程很多,真正要关注的不是安装那一刻的成功提示,而是装完以后服务能不能启动、root 能不能登录。
安装完成后第一件事是确认版本和服务状态:
mysql --version systemctl status mysqld # 无 systemd 的环境用 service mysql status如果命令提示找不到 mysql,说明安装时没有把 MySQL 的 bin 目录加入 PATH。Windows 上进入安装目录的 bin 文件夹再执行,或者把该目录手动加进环境变量。数据库密码是入门阶段最容易丢的东西,我一般建议装完立刻找一个地方记下来,忘记密码时重置流程对新手来说相当痛苦。mysql 下载官网的安装包通常区分 Installer 和精简版,学习用途选 Server only 就够了,不要被一堆附带组件带偏。
3.2 命令行导入 .sql:建库、导入、验证三连
不管源码包里的脚本是 .sql 后缀还是写成 .txt,最终都要交给 MySQL 执行。命令行是最不挑环境的做法,也是排除问题最直接的方式。
# 1. 建立目标库,明确字符集 mysql -uroot -p -e "CREATE DATABASE IF NOT EXISTS example_db DEFAULT CHARACTER SET utf8mb4;" # 2. 把脚本导入刚刚建好的库 mysql -uroot -p example_db < /path/to/example.sql # 3. 验证表是否进来 mysql -uroot -p -e "USE example_db; SHOW TABLES;"第一步里的 -e 表示执行单条命令后退出,不需要进入交互式界面。建库时直接指定 utf8mb4,后面导入中文数据才不容易乱码。第二步用 < 做输入重定向,让 mysql 客户端把文件内容当作一条条 SQL 去执行,它是命令行导入最常用的姿势。第三步的 SHOW TABLES 用来确认表到底进来没有,这一步不能省。有些教材脚本开头自带 CREATE DATABASE 和 USE 语句,那就不需要手工建库,直接执行第二步即可;如果脚本里使用了特定库名,而你手工建库时用了另一个名字,导入后 SELECT 会报 Table doesn't exist。
导入报错时先别怀疑脚本,用 head 看一眼文件开头:
head -n 20 /path/to/example.sql重点看有没有 SET NAMES、CREATE DATABASE、USE 这几类语句。开头几行能告诉你这个文件的字符集策略和是否内置建库逻辑。教材源码一般不会故意写坏,大多数导入失败都是环境问题。
3.3 Workbench / Navicat 导入:图形界面也有坑
图形客户端操作直观,适合新手,但最容易翻车的地方是字符集和当前库的选择。常见做法是先用客户端创建同名库,再选择“运行 SQL 脚本”,导入前核对文件编码。如果弹窗里有 Default Character Set 选项,选 utf8mb4;导入后中文变问号,八成是文件本身是 GBK 而连接用 UTF-8,或者正好反过来。
file /path/to/example.sqlfile 命令能直接读出文件编码,比如显示 ISO-8859 或者 UTF-8 Unicode text。拿到结果再决定怎么导入。要是嫌麻烦,命令行下用 --default-character-set 参数可以强制指定:
mysql -uroot -p --default-character-set=gbk example_db < /path/to/example.sql这个参数只影响客户端这一侧的连接字符集,不会改动表结构。还有一类情况是图形工具把整个脚本放在一个事务里执行,某条语句失败会整体回滚,报错信息被吞掉,很难定位。遇到这种诡异情况,立刻切到命令行用 source 方式执行,报错会逐条显示,哪个文件哪一行出错一目了然:
mysql -uroot -p USE example_db; source /path/to/example.sql;source 是 mysql 客户端的内建命令,等价于 . ,它逐条读取文件里的语句并上报错误,不会因为一条语句失败就把前面所有操作全部回滚。图形界面连不上时,先确认连接配置里 host 写的是 127.0.0.1 而不是 localhost,前者走 TCP,后者在部分系统上会尝试走 socket,服务监听方式不同会引发连接失败,这类问题最像玄学,实际上只是协议差异。
4. 从源码到可运行:连接串参数、驱动类名与一次增删改查
4.1 用 Python 验证环境:pymysql 最小连接
源码包里真正“跑起来”的入口是连接程序。在打开那些复杂的 Java 项目之前,我会先写一个最小连接脚本,验证端口、账号、密码、目标库四个条件是否同时满足。这一步能过滤掉一半以上的环境问题。
import pymysql conn = pymysql.connect( host="127.0.0.1", # 用 TCP 而不是 localhost,避免走 socket port=3306, # MySQL 默认端口 user="root", password="你的密码", # 换成安装时设置的 root 密码 database="example_db", # 前面建好的库 charset="utf8mb4", # 连接字符集,中文不乱码的关键 ) cursor = conn.cursor() cursor.execute("SELECT * FROM student LIMIT 5;") for row in cursor.fetchall(): print(row) cursor.close() conn.close()host 写成 127.0.0.1 而不是 localhost,是为了强制走 TCP 连接。代码跑不通时先看报错类型:ImportError 说明缺库,执行 pip install pymysql;OperationalError 则聚焦账号和端口;ProgrammingError 大概率是 SQL 里引用了不存在的表,回第 3 章查导入是否成功。注意教材配套源码里如果是 Python 2 语法,print 语句和游标取数方式在 Python 3 下需要小改,把 row[0] 改成 row["字段名"] 已经不是最佳实践,建议直接使用字典游标:
cursor = conn.cursor(pymysql.cursors.DictCursor)加了这行之后,每行结果就是字典结构,键名是字段名,代码可读性好很多。这个最小脚本留在手边,后面跑实战项目遇到连接问题,都用它来做交叉验证。
4.2 Java JDBC:驱动类名为什么一直在变
微课版源码里的 Java 示例通常会出现两种驱动写法。老教材写的是 com.mysql.jdbc.Driver,新版官方驱动把类名改成了 com.mysql.cj.jdbc.Driver。用新版驱动运行老代码,会抛 ClassNotFoundException,这不是源码写错了,而是驱动版本前进后留下的历史包袱。
import java.sql.*; public class TestMySQL { public static void main(String[] args) throws Exception { // MySQL 8.x 官方驱动的类名,老代码里写的老类名需要改这里 Class.forName("com.mysql.cj.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/example_db" + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"; Connection conn = DriverManager.getConnection(url, "root", "你的密码"); Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("SELECT * FROM student;"); while (rs.next()) { System.out.println(rs.getString("name") + " " + rs.getInt("age")); } conn.close(); } }url 里的 serverTimezone 参数在新驱动下几乎必须带,否则碰时间字段就报时区异常。useSSL 在本机学习环境可以关掉,省去证书配置。如果源码里的连接代码写的是老类名,最快的改法是只改 Class.forName 这一行,其余不需要动。还有一种情况是驱动 jar 没有放进 classpath,运行时报找不到类,本质也和代码无关,检查工程依赖比检查源码更快。这类问题在 mysql 面试题里也常被拿出来问,理解类名变迁比死记硬背更划算。
4.3 把例题改成小实训:改表名、加字段、加索引
源码包里的例题数据量往往很小,跑一遍看不出性能差异。要让它变成有挑战性的实训,我常用的做法是“旧瓶装新酒”,保留查询结构,把表和数据换成自己的练习版本。这一招对任何教材源码都适用。
-- 把 student 表复制成练习表,并加两个字段 CREATE TABLE emp AS SELECT * FROM student; ALTER TABLE emp ADD email VARCHAR(50) NOT NULL DEFAULT ''; ALTER TABLE emp ADD INDEX idx_age(age); -- 改成自己的查询需求 SELECT name, age FROM emp WHERE age > 20 ORDER BY age DESC;ALTER 一次只做一件事,出现错误时位置明确。加索引不是为了这几十行数据真的变快,而是为了后面用 EXPLAIN 看执行计划时,能直观对比全表扫描和索引扫描的差别。改完表和字段之后,可以继续把这套数据挪到存储过程里练手,比如把上面的查询包成带参数的过程。到这一步,例题实际上已经被扩展成实训,比直接背教材更有收获。
5. 避坑指南:这套源码翻车率最高的 5 个故障现象与解法
5.1 登录就报 ERROR 2002:服务没起来
现象:mysql -uroot -p 回车后出现 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)。
原因:MySQL 服务没有启动。Linux 和 macOS 上默认不会开机自启,Windows 上可能安装时没有注册服务,或者服务被防火墙拦住。
解决:
# Linux 先看服务状态,再启动 systemctl status mysqld systemctl start mysqld # macOS 如果用 Homebrew 安装 brew services start mysqlWindows 用户在“服务”管理里找到 MySQL 开头的服务项,右键启动。报错里的 /tmp/mysql.sock 只是 socket 文件路径,重点永远是服务状态。服务启动后如果还连不上,检查端口是否监听:
netstat -tlnp | grep 3306没有输出说明 mysqld 没起来,有输出但连不上则多半是权限或密码问题,和源码无关。
5.2 导入 .sql 报 Unknown collation:版本差异
现象:导入教材脚本时,MySQL 直接报 Unknown collation: 'utf8mb4_0900_ai_ci'。
原因:这个排序规则是 MySQL 8.0 的默认值。把 8.0 环境导出的脚本拿回 5.7 执行,5.7 根本不认识它,于是整个导入中断。
解决:把脚本里所有这个排序规则批量替换成 5.7 支持的写法。
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g' example.sql如果没有 sed,用编辑器全局替换也行。替换后再导入,问题消失。另一条路是直接用 8.0 建库导入,不换环境也不替换,反而省事。遇到这种问题不是脚本写错,只是两个版本不在同一个时代,不用怀疑教材。
5.3 中文全部显示为问号:字符集三层不一致
现象:SELECT 出来的中文全是 ???,或者导入后表里的数据直接乱码。
原因:连接字符集、表字符集、文件原始编码三层不一致。教材源码里常见的是 GBK 编码脚本,而你用 UTF-8 客户端执行,两边对不上。
解决:
mysql -uroot -p --default-character-set=gbk example_db < /path/to/example.sql如果文件本身是 UTF-8,就不要画蛇添足,保持 utf8mb4 即可。自查手段是看原始编码和表结构:
file /path/to/example.sql mysql -uroot -p -e "SHOW CREATE TABLE example_db.student;"file 结果和 SHOW CREATE TABLE 里的 CHARSET 对上,乱码基本消失。这是学习阶段最常踩的坑,也是最容易自我排查的坑。
5.4 Java 报 ClassNotFoundException: com.mysql.jdbc.Driver
现象:Java 示例编译成功,运行时报找不到驱动类。
原因:新版官方驱动把类从 com.mysql.jdbc.Driver 移到了 com.mysql.cj.jdbc.Driver。老教材源码用的是旧写法,和当前驱动不匹配。
解决:改代码里的这一行,不要费劲去找旧版驱动强行匹配。
Class.forName("com.mysql.cj.jdbc.Driver");顺手把连接 url 里的 serverTimezone 参数补上。这个报错在工程里还有一种变体,是驱动 jar 根本没放进 classpath,Maven 项目检查依赖配置,普通项目检查 lib 目录。两种原因都排除后,再把连接串打出来看有没有写错库名。
5.5 导入存储过程和函数报语法错误:DELIMITER 被误解
现象:用图形客户端执行整个 SQL 文件,在 CREATE PROCEDURE 处报语法错误,前面建表语句却正常执行。
原因:存储过程体内包含分号,客户端把分号当成整条语句的结束位置,于是过程体被截断,自然报错。文本脚本里通常会写 DELIMITER // 来临时改变结束符,但部分工具对 DELIMITER 的支持不完整。
解决:把存储过程部分单独复制出来,放到查询窗口手工执行;或者命令行进入 mysql 后使用 source 执行整个文件。文件里如果没有 DELIMITER,自己补上:
DELIMITER $$ CREATE PROCEDURE get_student(IN sid INT) BEGIN SELECT * FROM student WHERE id = sid; END$$ DELIMITER ;DELIMITER 是客户端指令,只改变客户端判断“语句边界”的方式,不会发给服务器。记住这一点,以后在任何工具里遇到存储过程导入失败都能快速反应过来。
6. 把源码用出价值:用例题练 EXPLAIN、存储过程和连接池三板斧
教材例题的数据量太小,跑一遍看不出水平。想让这套源码发挥真正的价值,我会把它改造成三个练习,难度平滑上升。
第一个练习是 EXPLAIN。在已经加了索引的 emp 表上执行 EXPLAIN SELECT * FROM emp WHERE age > 20;,先看 type 列是 ALL 还是 range,再把索引删掉对比一次。亲眼看到全表扫描和索引扫描的区别,比背十遍索引原理都管用。
第二个练习是存储过程。把例题里反复出现的查询包成 CREATE PROCEDURE,用 DELIMITER 处理好边界,再通过 CALL 语句传参调用。教材里可能只给了简单的查询脚本,但存储过程是面试高频考点,源码里的表结构正好当实验台。
第三个练习是连接池。把 Java 里 DriverManager 获取连接的方式换成连接池写法,比如 HikariCP 或 DBCP。最小配置只需要数据源、账号、密码三项。本地学习环境不需要调复杂参数,跑通一次连接池的获取与归还流程,后面接触 Spring 整合时才不会对连接池只有抽象概念。
我自己最早学存储过程时也只在图形工具里跑,直到做实战项目导入才发现 DELIMITER 才是隐藏难点。现在拿到任何一份教材源码,我都先建库、再看编码、再跑一次最小连接,顺序不乱。这套方法帮我处理过不止一份教程源码,也帮你把“能看懂的代码”变成“能跑通的技能”。希望帮到你。
本文还有配套的精品资源,点击获取