MySQL 相关知识及面试问题汇总

一、前言

对以往接触到的 MYSQL 相关技术及面试中有可能遇到的问题进行汇总整理(不定期更新),方便未来查阅复习。

二、MySQL 简介

MySQL 是目前世界上最流行的开源关系型数据库管理系统(RDBMS),基于 client-server 架构,使用 SQL 进行数据管理。由于其高性能、高可靠性、易用性及开源免费的特性,被广泛用于互联网应用(如 Facebook,Twitter,淘宝等)作为数据存储层。

三、相关知识

3.1 事务隔离级别

事务的四大特性 ACID(原子性、一致性、隔离性、持久性),为了解决并发事务带来的问题(脏读、不可重复、幻读),SQL 标准定义了四种隔离级别。

|-----------------------|------------------------------|----|-------|-----------------|
| 隔离级别 | 描述 | 脏读 | 不可重复读 | 幻读 |
| Read Uncommitted 读未提交 | 一个事务可以读取另一个未提交事务的数据 | ✅ | ✅ | ✅ |
| Read Committed 读已提交 | 一个事务只能读取已经提交的事务的数据(Oracle默认) | ❌ | ✅ | ✅ |
| Repeatable Read 可重复读 | 同一事务中多次读取的结果一致(InnoDB 默认) | ❌ | ❌ | ✅ InnoDB多数场景可避免 |
| Serializable 串行化 | 强制事务串行执行 | ❌ | ❌ | ❌ |

3.2 MVCC(多版本并发控制)原理

MVCC 是 InnoDB 实现 Read Committed 和 Repeatable Read 隔离级别的核心机制,它通过保存数据在某个时间点的快照,使得读操作不需要加锁,大大提高了并发性能。

核心组成:

  • 隐藏字段:InnoDB 会给每行数据添加三个隐藏字段:
    • DB_TRX_ID:最近修改(或插入)该行数据的事务 ID;
    • DB_ROLL_PTR:回滚指针,指向 Undo Log 中上一个版本的记录;
    • DB_ROW_ID:隐藏的主键(如果表没有主键)。
  • Undo Log(回滚日志):当事务修改数据时,MySQL 会将旧数据写入 Undo Log,通过回滚指针,形成一条版本链。
  • Read View(读视图):事务进行快照读时产生的读视图,它决定了事务能看到版本链中的哪条数据。
    • m_ids:生成 Read View 时,当前系统中活跃(未提交)的事务 ID 列表;
    • min_trx_id:活跃事务中最小的 ID;
    • max_trx_id:系统应该分配给下一个事务的 ID。

RC 与 RR 在 MVCC 上的区别:

  • Read Committed:在每一次进行普通 Select 操作前都会生成一个新的 Read View,所以它能读到别的事务刚刚提交的数据。
  • Repeatable Read:只在事务开启后的第一次 Select 操作前生成 Read View,之后复用这个 Read View,所以即使别的事务提交了修改,当前事务看到的依然是旧版本,从而实现了"可重复读"。
3.3 MySQL 的"三大日志"

MySQL 的数据安全和主从复制依赖于日志系统,最重要的是 Redo Log、Undo Log 和 Binlog。

  1. Redo Log(重做日志)- 物理日志
  • 作用:保证事务的持久性(Durability),实现 Crash-safe 能力。
  • 原理:WAL(Write-Ahead Logging)技术,先写日志,再写磁盘。
  • 特点:
    • InnoDB 存储引擎层特有的。
    • 记录的是"在某个数据页上做了什么修改"。
    • 是循环写的,固定大小,写满后需要擦除旧记录(Checkpoint)。
  1. Undo Log(回滚日志)- 逻辑日志
  • 作用:保证事务的原子性(Atomicity)和实现 MVCC。
  • 原理:记录数据的逻辑变化。例如执行一条 INSERT,Undo Log 就记录一条 DELETE;执行 UPDATE,就记录相反的 UPDATE。
  • 场景:事务回滚时,通过 Undo Log 将数据恢复到修改前的样子。
  1. Binlog(归档/二进制日志)- 逻辑日志
  • 作用:用于主从复制和数据恢复(如误删库后的恢复)。
  • 特点:
    • 是 MySQL Server 层实现的,所有引擎都可以使用。
    • 是追加写的,不会覆盖旧日志。
    • 记录的是 SQL 语句的原始逻辑(如 Statement 格式)或行数据的变更(Row 格式)。

四、面试问题

4.1 为什么 InnoDB 选择 B+ 树作为索引结构,而不是 B 树或 Hash
  • Hash 查询效率极高,但不支持范围查询和排序;
  • B 树的每个节点都存储数据,B+ 树只有叶子结点存储数据,非叶子结点只存索引
    • 非叶子结点能容纳更多索引,磁盘 I/O 次数更少;
    • B+ 树的叶子结点通过双向链表连接,范围查询时只需遍历链表,而 B 树需要进行中序遍历。
4.2 聚簇索引和非聚簇索引
  • 聚簇索引
    • 数据行和相邻的键值紧凑地存储在一起;
    • InnoDB 的主键索引就是聚簇索引,叶子结点存储的是整行数据;
    • 一张表只能有一个聚簇索引。
  • 非聚簇索引
    • 叶子节点存储的是索引列的值和主键 ID;
    • 回表:如果通过二级索引查询非索引列的数据,需要先拿到主键 ID,再去聚簇索引(主键索引)中查找完整的行数据,这个过程叫回表。
4.3 最左前缀原则

假设有一个联合索引(a, b, c),查询条件必须从最左边列开始匹配。

  • 如果查询条件是 where a=1 and b=2,命中索引;
  • 如果查询条件是 where b=2 and c=3,不命中索引;
  • 如果查询条件是 where a=1 and c=3,a 列命中索引,c 列不命中索引;
  • 如果遇到范围查询(>, <, between, like),停止匹配后续列,查询条件是 where a=1 and b>2 and c=3,a 和 b 命中索引,c 不命中索引。

参考资料

相关推荐
江湖十年4 小时前
Go 并发控制:sync.Pool 详解
后端·面试·go
rainbow7242444 小时前
AI人才简历评估选型:技术面试、代码评审与项目复盘的综合运用方案
人工智能·面试·职场和发展
张张123y4 小时前
RAG从0到1学习:技术架构、项目实践与面试指南
人工智能·python·学习·面试·架构·langchain·transformer
努力学算法的蒟蒻5 小时前
day115(3.17)——leetcode面试经典150
面试·职场和发展
Baihai_IDP6 小时前
OpenClaw 架构详解 · 第一部分:控制平面、会话管理与事件循环
人工智能·面试·llm
张李浩6 小时前
Leetcode 15三题之和
算法·leetcode·职场和发展
小涛不学习9 小时前
HTTP 和 HTTPS 详解(原理 + 区别 + 面试重点)
http·面试·https
Moment9 小时前
MiniMax 发布 M2.7,Agent 开始走向自我进化
前端·后端·面试
发现一只大呆瓜9 小时前
Vue-Vue Router核心原理+实战用法全解析
前端·vue.js·面试
做怪小疯子9 小时前
Leetcode刷题——8.重叠区间
算法·leetcode·职场和发展