MySQL SQL基础练习:从入门到实战100题

MySQL SQL基础练习:从入门到实战100题

1. MySQL SQL基础练习的价值与适用场景

对于任何需要与数据库打交道的开发者来说,SQL都是必须掌握的看家本领。我见过太多简历上写着"精通MySQL"的候选人,面对简单的多表联查时却手足无措。这100道基础练习题就像武术中的马步训练,看似枯燥却能夯实你的底层能力。

这套练习特别适合三类人群:

  • 刚学完SQL语法但缺乏实战的新手(建议先掌握SELECT/INSERT/UPDATE/DELETE等基础语法)
  • 准备数据库相关面试的求职者(覆盖80%的初级SQL面试题)
  • 工作中需要偶尔写SQL但总记不住语法的非专职DBA

我在带团队时有个习惯:让所有新人在入职第一周完成这100题并讲解思路。这个简单的测试能快速暴露SQL思维的薄弱环节,比如有人对JOIN的理解停留在理论层面,有人面对复杂条件查询就本能地想写多个简单查询。

2. 练习环境快速搭建指南

2.1 MySQL安装方案选型

虽然练习题可以在任何MySQL环境完成,但我推荐使用Docker快速搭建隔离的练习环境:

docker run --name mysql-practice -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:8.0

为什么选择这个方案?

  • 版本统一:避免"我本地是5.7但生产用8.0"的兼容性问题
  • 隔离性:不会污染本地已有的MySQL实例
  • 可销毁:练习完直接docker rm -f mysql-practice不留痕迹

注意:生产环境务必使用更复杂的密码,这里仅为练习方便

2.2 初始化练习数据库

我准备了一个经典的员工管理数据库模型,包含以下表:

  • employees(员工基本信息)
  • departments(部门信息)
  • salaries(薪资记录)
  • dept_emp(部门-员工关系)
  • titles(职称记录)

执行以下命令获取并初始化数据:

wget https://example.com/employee_db.sql # 示例URL,实际需替换 mysql -h 127.0.0.1 -P 3306 -u root -p123456 < employee_db.sql

3. 核心练习题分类解析

3.1 单表查询基础(20题)

这部分看似简单却暗藏玄机,重点训练:

  • SELECT字段选择与别名使用
  • WHERE条件组合(特别是BETWEEN、IN、LIKE等易错操作符)
  • DISTINCT去重的实际应用场景
  • ORDER BY多字段排序策略

典型题目示例:

-- 找出1990年后入职的女性员工,按部门分组统计人数 SELECT d.dept_name, COUNT(*) AS female_count FROM employees e JOIN dept_emp de ON e.emp_no = de.emp_no JOIN departments d ON de.dept_no = d.dept_no WHERE e.gender = 'F' AND e.hire_date > '1990-01-01' GROUP BY d.dept_name HAVING COUNT(*) > 5;

3.2 多表连接实战(30题)

JOIN是SQL的核心难点,这部分重点训练:

  • INNER JOIN与LEFT JOIN的本质区别(建议用Venn图辅助理解)
  • 多表连接的执行顺序与性能影响
  • 自连接的特殊应用场景(如查找同一部门的员工对)

避坑指南:

  • 永远明确指定JOIN条件,避免笛卡尔积
  • 多表连接时使用表别名提高可读性
  • 超过3个表连接时考虑使用WITH子句拆分逻辑

3.3 聚合函数与分组统计(20题)

从简单计数到复杂分析:

  • GROUP BY与HAVING的配合使用
  • 窗口函数初探(RANK、DENSE_RANK等)
  • ROLLUP实现多级分组统计

典型错误案例:

-- 错误:SELECT列表包含非聚合字段 SELECT dept_no, emp_no, -- 这里会报错 AVG(salary) FROM salaries GROUP BY dept_no;

3.4 子查询与复杂逻辑(20题)

包括:

  • EXISTS与IN的性能对比
  • 相关子查询执行机制
  • 使用派生表简化复杂查询

优化技巧:

  • 将深度嵌套的子查询重构为JOIN
  • 使用CTE(WITH子句)提高可读性
  • 避免在WHERE子句中对字段使用函数

3.5 数据修改与事务控制(10题)

实战重点:

  • UPDATE使用JOIN实现跨表更新
  • 事务的ACID特性验证实验
  • 悲观锁与乐观锁模拟

重要提醒:

-- 永远先写SELECT确认再转为UPDATE -- 错误示范(缺少WHERE条件) UPDATE employees SET salary = salary * 1.1; -- 全表更新!

4. 高效练习方法论

4.1 分阶段练习计划

建议的练习节奏:

  1. 基础阶段(1-50题):每天10题,重点理解语法
  2. 强化阶段(51-80题):每天5题,注重性能分析
  3. 实战阶段(81-100题):每题研究多种解法

4.2 使用EXPLAIN分析执行计划

对每道复杂题目都应查看执行计划:

EXPLAIN FORMAT=JSON SELECT ... [你的查询语句];

重点关注:

  • type列(最好达到ref或range)
  • possible_keys与实际使用的key
  • Extra列中的"Using filesort"等警告

4.3 建立个人SQL代码库

建议用Git管理所有练习答案,目录结构示例:

/sql-100/ ├── /01-basic/ │ ├── 01-select.sql │ └── 02-where.sql ├── /02-join/ ├── /03-aggregation/ └── README.md # 记录学习心得

5. 常见问题排错指南

5.1 错误代码速查表

错误代码典型原因解决方案
1064SQL语法错误检查引号、括号是否匹配
1146表不存在检查表名拼写和数据库选择
1055GROUP BY错误SELECT字段必须出现在GROUP BY或聚合函数中

5.2 性能优化检查清单

当查询执行缓慢时:

  1. 是否有适当的索引?(SHOW INDEX FROM table)
  2. 是否扫描了过多行?(EXPLAIN中的rows列)
  3. 是否可以重写为JOIN替代子查询?
  4. 是否使用了OR条件导致索引失效?

5.3 数据类型陷阱

常见问题:

  • VARCHAR比较时注意空格:'text' != 'text '
  • 日期范围查询包含边界:date <= '2020-12-31'是否包含当天?
  • 浮点数精度问题:避免直接等值比较

6. 进阶学习路径

完成这100题后建议:

  1. 学习索引原理与优化(B+树、覆盖索引等)
  2. 研究执行计划优化(optimizer trace)
  3. 了解MySQL架构(连接池、缓冲池等)
  4. 探索分布式数据库中间件(如ShardingSphere)

我个人的经验是:当你能把这100题中的复杂查询拆解为清晰的执行流程图时,就真正掌握了SQL思维。建议每半年重做一次这些题目,每次都会有新的理解。