会写单表查询,到了三张表一起查就容易绕晕。可以下载 MySQL 的 Sakila 示例库练手。它模拟一家影碟出租店,有电影、演员、库存和租借记录。表里的数据和关系都准备好了,导入后就能写查询。

下载的 ZIP 中,建表脚本标注为 Sakila 1.5。如果命令行工具收到 403,可以从上面的示例库列表用浏览器点 Sakila 那一行的 Zip。解压后,sakila-schema.sql 负责建库和表等对象,sakila-data.sql 用来填数据并创建需要在导入后设置的触发器。sakila.mwb 是给 MySQL Workbench 看表关系的模型文件,做查询练习时可以先放一边。 Sakila 官方安装文档

先建表,再灌数据

用单独的练习实例。 建表脚本会执行 DROP SCHEMA IF EXISTS sakila,重跑会删掉同名库。下面以本机的 MySQL 8.4 练习实例为例,假设它对外的端口是 3307。先确认端口确实指向练习实例,再用有建库、建表等权限的账号登录。把 root 换成你为这个实例准备的账号。

mysql --host=127.0.0.1 --port=3307 --user=root --password

下面三行在 mysql> 提示符里执行。这里用的是 Windows 解压路径,按实际位置替换。Linux 或 macOS 可以用 /tmp/sakila-db/ 之类的路径。两个 SOURCE 按顺序跑,第一份报错就先看报错的位置。

SOURCE C:/temp/sakila-db/sakila-schema.sql;
SOURCE C:/temp/sakila-db/sakila-data.sql;
SHOW FULL TABLES FROM sakila;

能看到表还只能说明结构已建好。接下来查一次电影和演员,顺带确认数据也导进来了。

查一部电影的演员,为什么要连三张表

电影和演员是多对多关系。同一部电影有多名演员,同一个演员也可能拍过多部电影。film_actor 只记录电影 ID 和演员 ID 的对应关系。片名去 film 拿,姓名去 actor 拿。 Sakila 官方表结构

USE sakila;

SELECT f.title, a.actor_id, a.first_name, a.last_name
FROM film AS f
JOIN film_actor AS fa ON fa.film_id = f.film_id
JOIN actor AS a ON a.actor_id = fa.actor_id
WHERE f.film_id = 1
ORDER BY a.actor_id;

结果里同一个片名会跟着不同的演员出现,每行是一对电影和演员。如果你要在页面上做“一部电影一行”,可以再试试按 f.film_id 和 f.title 分组,用 COUNT(*) 数每部电影的演员人数。想追一下数据库怎么连表,在同一条查询前加 EXPLAIN,看它选了哪些键。Sakila 适合练怎么看计划,业务库的耗时还得用业务库自己的数据来判断。 MySQL 查询突然变慢怎么查