MySQL

MySQL 基础知识面试题

·9 分钟阅读·3484 字

整理MySQL 基础知识高频问答、延伸追问与易错点

📋 目录

MySQL 基础知识面试题

1. mysqldump 备份

mysqldump -u root -p —all-databases > backup.sql mysqldump -u root -p db_name > db_backup.sql

2. 恢复

mysql -u root -p < backup.sql

mysql -u root -p db_name < db_backup.sql

`

物理备份:

`ash

3. Percona XtraBackup(热备,不锁表)

xtrabackup —backup —target-dir=/backup/

xtrabackup —prepare —target-dir=/backup/

`

备份方式优点缺点
mysqldump简单、可跨版本大数据量慢
XtraBackup快、热备、增量备份需额外安装工具
Binlog时间点恢复(PITR)需配合全量备份使用

3.1. 【延伸追问】

  1. 如何进行时间点恢复(Point-In-Time Recovery)?
  2. 备份的恢复演练应该多久做一次?

3.2. 【易错坑点】

  • ❌ 只有备份没有验证(备份文件损坏等于没备份)
  • ❌ 忽略 Binlog 的保留时间,导致无法 PITR

4. 索引不适合哪些场景?

4.1. 【题目】

索引在哪些场景下不适合使用?

4.2. 【参考答案】

  1. 数据量小的表:全表扫描比索引查询更快(MySQL 优化器会自动选择)
  2. 频繁更新的列:索引维护(B+ 树调整)开销大于查询收益
  3. 区分度低的列:如性别(男/女),扫描一半数据不如全表扫描
  4. 很少查询的列:索引占用空间,没有查询收益
  5. 长文本/二进制列:索引体积大且意义不大(可使用前缀索引)

4.3. 【延伸追问】

  1. 什么是区分度(Cardinality)?如何查看?
  2. 前缀索引如何设置合适的长度?

4.4. 【易错坑点】

  • ❌ 为所有列都建立索引(严重降低写入性能)
  • ❌ 忽略 MySQL 优化器可能不使用索引(即使有索引)

5. 脏读、不可重复读、幻读的解释

5.1. 【题目】

什么是脏读、不可重复读、幻读?

5.2. 【参考答案】

问题现象产生原因隔离级别解决
脏读事务 A 读到事务 B 未提交的数据写操作未提交即被读取READ COMMITTED 及以上
不可重复读同一事务内两次读取同一条记录返回不同数据其他事务修改并提交了该记录REPEATABLE READ 及以上
幻读同一事务内两次查询结果集数量不同(出现新行)其他事务插入/删除了记录SERIALIZABLE(或 InnoDB 的间隙锁解决)

`sql

— 不可重复读示例

— 事务 A:

SELECT balance FROM accounts WHERE id = 1; — 返回 100

— 事务 B: UPDATE accounts SET balance = 200 WHERE id = 1; COMMIT;

— 事务 A:

SELECT balance FROM accounts WHERE id = 1; — 返回 200(不可重复读)

`

5.3. 【延伸追问】

  1. InnoDB 如何通过 MVCC + Gap Lock 解决幻读?
  2. 在 READ COMMITTED 级别下如何避免不可重复读?

5.4. 【易错坑点】

  • ❌ 混淆不可重复读(同一条记录值变化)和幻读(结果集行数变化)
  • ❌ 误以为 REPEATABLE READ 能完全避免幻读(InnoDB 的 Next-Key Lock 实际上解决的是「当前读」下的幻读)

6. SQL 约束有哪几种?

6.1. 【题目】

SQL 约束有哪几种?

6.2. 【参考答案】

约束说明示例
NOT NULL字段值不能为 NULLname VARCHAR(50) NOT NULL
UNIQUE字段值唯一,允许 NULLemail VARCHAR(100) UNIQUE
PRIMARY KEY唯一标识每行,不允许 NULLid INT PRIMARY KEY
FOREIGN KEY引用另一张表的主键,保证引用完整性FOREIGN KEY (dept_id) REFERENCES dept(id)
CHECK字段值必须满足指定条件(MySQL 8.0.16+ 才真正生效)age INT CHECK (age >= 0)
DEFAULT为字段指定默认值status INT DEFAULT 1

6.3. 【延伸追问】

  1. CHECK 约束在 MySQL 8.0 之前为什么无效?(解析时忽略,不报错但也不检查)
  2. FOREIGN KEY 对性能有什么影响?(每次插入/更新需检查引用表)

6.4. 【易错坑点】

  • ❌ 误以为 MySQL 的 CHECK 约束一直有效(MySQL 8.0.16 前仅解析不执行)
  • ❌ 忽略外键对写入性能的影响

7. UNION 和 UNION ALL 的区别

7.1. 【题目】

UNION 和 UNION ALL 有什么区别?

7.2. 【参考答案】

特性UNIONUNION ALL
重复行去重(自动 DEDUP)包含重复行
排序会对结果排序(以去重)不排序
性能较慢(需要额外排序去重)更快
内存需要临时表去重直接追加结果

`sql

— UNION 去重效率低

SELECT name FROM employees_2023

UNION

SELECT name FROM employees_2024;

— UNION ALL 效率高(确认无重复时使用)

SELECT name FROM employees_2023

UNION ALL

SELECT name FROM employees_2024;

`

7.3. 【延伸追问】

  1. UNION 的去重逻辑是什么?(对所有 SELECT 的列做 DISTINCT)
  2. 什么场景下应该用 UNION ALL 替代 UNION?

7.4. 【易错坑点】

  • ❌ 随意使用 UNION 而不是 UNION ALL(导致不必要的去重排序开销)
  • ❌ 误以为 UNION 不会对结果排序(实际上为去重会排序)

8. 子查询及其用途

8.1. 【题目】

解释子查询及其用途。

8.2. 【参考答案】

子查询是嵌套在其他 SQL 查询中的查询,可以返回标量值、单列集合或多列结果。

`sql

— 标量子查询(返回单个值)

SELECT name, (SELECT MAX(salary) FROM employees) AS max_salary FROM departments;

— 行子查询(WHERE 条件中使用)

SELECT * FROM products

WHERE price > (SELECT AVG(price) FROM products);

— EXISTS 子查询

SELECT * FROM customers c

WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);

— FROM 子句中的派生表

SELECT avg_order.total

FROM (SELECT customer_id, COUNT(*) as total FROM orders GROUP BY customer_id) avg_order;

`

用途:

  • 在 WHERE 条件中比较聚合结果
  • 检查数据的存在性(EXISTS / NOT EXISTS)
  • 在 FROM 中作为派生表(临时结果集)

8.3. 【延伸追问】

  1. 子查询和 JOIN 的性能差异是什么?(子查询在某些场景下会产生临时表,性能低于 JOIN)
  2. 关联子查询(Correlated Subquery)和非关联子查询的区别?

8.4. 【易错坑点】

  • ❌ 滥用子查询导致性能问题(可用 JOIN 优化时优先使用 JOIN)
  • ❌ 忽略了 EXISTS 和 IN 子查询在某些场景下的性能差异

关联文档

Yanche Blog

记录云原生、Linux、数据库等技术领域的学习心得,以及日常生活的思考与感悟。

© 2026 Yanche Blog. All rights reserved.

Powered by Astro