1. MySQL SQL基础练习的价值与定位
作为一名数据库工程师,我经常被问到"如何系统掌握SQL基础"这个问题。市面上大多数教程要么过于理论化,要么缺乏足够的实践环节。而这套100道基础练习题正是我从业十年总结出的最佳入门路径——通过解决实际问题来掌握核心语法。
SQL作为关系型数据库的标准查询语言,其基础语法看似简单,但实际应用中存在大量细节差异。比如同样是查询数据,SELECT语句在不同业务场景下的优化策略可能截然不同。通过这套练习,你能快速建立对MySQL特性的认知框架。
提示:建议在MySQL 5.7或8.0版本环境下完成练习,这两个版本在企业环境中占比超过80%,语法兼容性最好。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 练习环境搭建与准备
2.1 MySQL安装配置要点
虽然练习题不依赖特定环境,但我推荐使用Docker快速搭建隔离的MySQL实例:
bash复制docker run --name mysql-practice -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
关键参数说明:
utf8mb4字符集支持完整Unicode(包括emoji)- 5.7版本在稳定性和性能之间取得较好平衡
- 密码复杂度建议高于示例中的"123456"
2.2 练习数据集设计
为全面覆盖各类场景,我设计了包含6张表的电商数据库模型:
- 用户表(users):用户基础信息
- 商品表(products):商品SKU数据
- 订单表(orders):订单主表
- 订单明细(order_items):商品购买明细
- 评价表(reviews):用户评价记录
- 物流表(logistics):配送跟踪信息
sql复制CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
reg_date DATETIME NOT NULL,
last_login DATETIME,
vip_level TINYINT DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心题型分类解析
3.1 单表查询进阶技巧
第1-30题聚焦SELECT语句的深度运用,几个典型示例:
场景1:处理NULL值
sql复制/* 找出从未登录过的用户(last_login为NULL) */
SELECT user_id, username
FROM users
WHERE last_login IS NULL;
场景2:日期函数应用
sql复制/* 计算用户注册天数并筛选老用户 */
SELECT user_id,
username,
DATEDIFF(NOW(), reg_date) AS reg_days
FROM users
WHERE DATEDIFF(NOW(), reg_date) > 365;
注意:MySQL中NULL的比较永远返回NULL,要用IS NULL/IS NOT NULL判断
3.2 多表连接实战
第31-60题涵盖各种JOIN场景,重点题型:
三表关联查询
sql复制/* 查询VIP用户的未发货订单详情 */
SELECT u.username, o.order_no, p.product_name
FROM users u
JOIN orders o ON u.user_id = o.user_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE u.vip_level > 0
AND o.status = 'unshipped';
连接类型选择原则:
- INNER JOIN:默认选择,性能最优
- LEFT JOIN:需保留左表全部记录时使用
- RIGHT JOIN:MySQL中较少使用
3.3 聚合与分组统计
第61-80题训练数据分析能力:
复杂分组统计
sql复制/* 按月统计各商品类别的销售额TOP3 */
WITH monthly_sales AS (
SELECT
DATE_FORMAT(o.create_time, '%Y-%m') AS month,
p.category,
SUM(oi.price * oi.quantity) AS sales_amount
FROM orders o
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE o.status = 'completed'
GROUP BY month, p.category
)
SELECT * FROM (
SELECT
month,
category,
sales_amount,
RANK() OVER (PARTITION BY month ORDER BY sales_amount DESC) AS sales_rank
FROM monthly_sales
) ranked
WHERE sales_rank <= 3;
4. 高阶特性专项训练
4.1 窗口函数实战
MySQL 8.0+支持的窗口函数能简化复杂分析:
sql复制/* 计算用户消费金额与同等级VIP平均消费的对比 */
SELECT
user_id,
username,
vip_level,
total_spent,
AVG(total_spent) OVER (PARTITION BY vip_level) AS avg_level_spent,
total_spent - AVG(total_spent) OVER (PARTITION BY vip_level) AS diff_from_avg
FROM (
SELECT
u.user_id,
u.username,
u.vip_level,
SUM(oi.price * oi.quantity) AS total_spent
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
LEFT JOIN order_items oi ON o.order_id = oi.order_id
WHERE o.status = 'completed'
GROUP BY u.user_id
) user_stats;
4.2 事务与锁机制
第91-95题模拟并发场景:
sql复制START TRANSACTION;
/* 查询库存并加锁 */
SELECT stock FROM products WHERE product_id = 1001 FOR UPDATE;
/* 模拟业务处理 */
DO SLEEP(5);
/* 更新库存 */
UPDATE products SET stock = stock - 1 WHERE product_id = 1001;
COMMIT;
重要:FOR UPDATE是悲观锁的实现方式,在高并发下单系统中至关重要
5. 性能优化实践
5.1 索引设计原则
结合练习题中的查询模式,最优索引策略:
sql复制/* 订单表复合索引 */
ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);
/* 订单明细覆盖索引 */
ALTER TABLE order_items ADD INDEX idx_order_product (order_id, product_id);
索引设计要点:
- 优先考虑WHERE和JOIN条件中的字段
- 区分度高的字段靠左(如user_id比status区分度高)
- 避免过度索引,影响写入性能
5.2 EXPLAIN实战分析
第96-100题专门训练执行计划解读:
sql复制EXPLAIN
SELECT u.username, COUNT(*) AS order_count
FROM users u
JOIN orders o ON u.user_id = o.user_id
WHERE u.reg_date > '2023-01-01'
GROUP BY u.user_id
HAVING order_count > 3;
关键指标解读:
- type列:应至少达到range级别
- possible_keys:显示可能使用的索引
- rows:预估扫描行数(越小越好)
6. 常见问题排查指南
6.1 语法错误TOP5
- GROUP BY遗漏:SELECT中的非聚合字段必须出现在GROUP BY中
- 引号混用:MySQL中字符串必须用单引号
- 别名使用:WHERE中不能使用SELECT中定义的别名
- 隐式类型转换:避免WHERE user_id = '1001'这类写法
- 保留字冲突:如使用
rank等关键字需加反引号
6.2 性能陷阱
-
全表扫描:未命中索引的查询
- 解决方案:添加适当索引或重写查询条件
-
临时表:GROUP BY、DISTINCT等操作可能产生
- 解决方案:优化索引或调整SQL写法
-
隐式排序:ORDER BY NULL可以取消不必要的排序
7. 学习路径建议
根据练习完成情况,推荐进阶路线:
-
基础巩固(完成1-60题):
- 《MySQL必知必会》
- 官方文档Basic Statements章节
-
性能优化(完成61-90题):
- 《高性能MySQL》第5章
- 学习EXPLAIN的所有输出字段含义
-
高阶特性(完成91-100题):
- 窗口函数专项训练
- 事务隔离级别实验
这套练习题我每年都会带新人完整做一遍,最大的体会是:SQL能力的提升不在于知道多少语法,而在于遇到实际问题时能否快速拆解为有效的查询逻辑。建议每个题目至少尝试三种不同写法,比较执行计划和性能差异。
