For AI agents: the complete documentation index is available at https://tingfeng347.github.io/windwiki/llms.txt, the full documentation bundle is available at https://tingfeng347.github.io/windwiki/llms-full.txt, and this page is available as Markdown at https://tingfeng347.github.io/windwiki/terminology/mysql-database.md.

MySQL 与数据库 · 面试清单

面试权重:★★★★★ 后端面试被问得最多的一块,也是「日常在用、一问原理就露底」最多的一块。


一、基础与存储引擎

术语一句话释义
关系模型数据以二维表组织,用主键唯一标识行、外键表达引用关系
三大范式1NF 字段原子;2NF 消除部分依赖;3NF 消除传递依赖——工程上会为性能刻意反范式
InnoDBMySQL 5.5+ 默认引擎,支持事务、行锁、外键、崩溃恢复;绝大多数业务表都用它
MyISAM不支持事务与行锁,只有表锁,崩溃后易损坏;已被 InnoDB 取代
Memory 引擎数据放内存、重启即失,适合临时表
字符集与排序规则统一用 utf8mb4 + utf8mb4_0900_ai_ci,utf8 存不了 emoji
数据类型选择能用整型不用字符串、能定长不定长、金额用 DECIMAL 而非 FLOAT(浮点会丢精度)
EXPLAIN看优化器选的执行计划,重点看 type、key、rows、Extra
EXPLAIN ANALYZE8.0.18+ 给的是真实执行统计(实际行数、耗时),比估算值更可信
SHOW PROFILE / 慢查询日志慢日志 slow_query_log + long_query_time 是定位慢 SQL 的起点

二、索引

术语一句话释义
索引的本质用额外空间换查询速度的有序数据结构,代价是写放大
B+ 树为什么合适非叶节点只存键、树矮(3~4 层可存千万级)、叶子链表天然支持范围扫描,磁盘 IO 少
B+ 树 vs B 树B 树每个节点都存数据导致扇出小、树更高;B+ 树数据只在叶子且有链表
B+ 树 vs 哈希索引哈希是 O(1) 等值但不支持范围、排序、最左前缀
聚簇索引 Clustered叶子节点直接存整行数据,InnoDB 的主键索引即聚簇索引
二级索引(辅助索引)叶子存主键值,查非索引列需回表
回表先在二级索引拿到主键,再回聚簇索引取整行,多一次查找
覆盖索引 Covering Index查询所需列全在索引里,免回表;EXPLAIN 的 Extra 出现 Using index
联合索引多列按定义顺序组成一个索引,先按第一列排、再按第二列排
最左前缀原则联合索引只能从最左列开始连续匹配;中间断掉则后面的列失效
范围条件的位置范围查询之后的列不再能用于索引定位(但 8.0 有索引下推与跳跃扫描可部分缓解)
索引下推 ICP把 WHERE 条件下推到存储引擎在索引层过滤,减少回表次数(Using index condition)
索引跳跃扫描 Skip Scan8.0.13+ 在最左列基数很低时也能用上联合索引
索引失效的典型场景左模糊 %x、列上用函数或运算、隐式类型转换、OR 连接非索引列、!=/NOT IN 有时失效
选择性与基数区分度 = 不同值数 / 总行数;区分度低的列(性别)单建索引意义不大
前缀索引长字符串只用前 N 个字符建索引,省空间但不能用于覆盖索引
索引合并 Index Merge优化器用多个单列索引求交/并,通常是联合索引缺失的信号
冗余与重复索引已有 (a,b) 时再建 (a) 是冗余,白白增加写开销
索引统计信息innodb_stats_persistent 控制持久化统计,统计失真会导致选错执行计划

三、查询优化与实践

术语一句话释义
type 访问类型system > const > eq_ref > ref > range > index > ALL,出现 ALL 基本意味着全表扫
Extra 重点值Using index(覆盖)、Using filesort(额外排序)、Using temporary(临时表)、Using index condition(ICP)
Using filesort 的解法让 ORDER BY 的列顺序与联合索引一致,并避免范围条件破坏排序
Using temporary 的解法常见于 GROUP BY 无合适索引或 UNION,加索引或改写 SQL
COUNT(*) vs COUNT(col)COUNT(*) 不忽略 NULL 且走最小的索引,COUNT(col) 会跳过 NULL 且可能无法用索引
深分页问题LIMIT 1000000,10 要扫掉前一百万行;解法是游标(WHERE id > ?)或延迟关联
JOIN 算法小表驱动大表;被驱动表的关联列必须有索引,否则退化成笛卡尔积级扫描
IN vs EXISTS子查询小用 IN,外表小用 EXISTS;IN 列表过长要考虑分批或临时表
分区表 Partition按范围/哈希把一张表拆成多个物理分区,对应用透明;跨分区查询仍可能很慢
分库分表水平(按行拆)与垂直(按列拆);引入路由、全局 ID、跨库 JOIN 与分布式事务等新问题
分片键选择要兼顾分布均匀与查询能命中单片,否则广播查询会吃掉收益
在线 DDLMySQL 5.6+ 多数加索引支持 Online DDL,但大表仍建议 gh-ost / pt-osc 平滑变更
SQL 注入参数化查询(预编译)是唯一可靠解法,拼接字符串必然有风险
慢 SQL 治理闭环慢日志/APM 发现 → EXPLAIN 定位 → 改写或加索引 → 回归验证 → 加监控防复发

四、事务与隔离级别

术语一句话释义
ACID原子性、一致性、隔离性、持久性;A/I/D 由 undo/隔离机制/redo 保障,一致性是目的
脏读 Dirty Read读到别的事务未提交的数据
不可重复读同一事务内两次读同一行结果不同(别的事务改了并提交)
幻读 Phantom同一事务内两次范围查询行数变多(别的事务插入并提交)
读未提交 RU什么都不隔离,只解决「第一类更新丢失」
读已提交 RC只读已提交数据,Oracle/PostgreSQL 默认;每次 SELECT 生成新快照
可重复读 RRMySQL 默认;事务内快照固定,靠 Next-Key Lock 基本消除幻读
串行化 Serializable加范围锁,完全串行;并发最差
快照读 vs 当前读普通 SELECT 是快照读(走 MVCC,无锁);SELECT ... FOR UPDATE/UPDATE/DELETE 是当前读(加锁)
RR 下仍然可能出现幻读的情况快照读与当前读混用,或先快照读再用当前读更新
长事务的危害撑大 undo 表空间、阻塞 purge、导致锁等待与主从延迟——线上排查优先看 information_schema.innodb_trx
autocommit默认开启,每条语句自成一个事务;写脚本要注意这点

五、MVCC 与锁

术语一句话释义
MVCC多版本并发控制,用版本链让读写互不阻塞,是「无锁读」的基础
隐藏列每行有 DB_TRX_ID(最后修改的事务 ID)与 DB_ROLL_PTR(指向上个版本)
undo log 版本链每次修改把旧值写入 undo,用回滚指针串成链表
ReadView快照读时生成的「活跃事务列表」,用它判断某版本是否可见
可见性规则版本的 trx_id 比最小活跃事务还小且已提交则可见;在活跃集合里则不可见,沿链往前找
RC vs RR 的 ReadView 时机RC 每条 SELECT 都重建 ReadView;RR 只在事务第一次快照读时生成一次
purge 线程清理不再被任何 ReadView 需要的旧版本
表锁 vs 行锁InnoDB 默认行锁,但无索引的更新会退化为锁全表(锁的是所有扫描到的行)
共享锁 S / 排他锁 XS 与 S 兼容、与 X 互斥;LOCK IN SHARE MODE / FOR UPDATE
意向锁 IS / IX表级标志,表示「表内某行被加锁」,用于快速判断表锁能否加上
记录锁 / 间隙锁 / 临键锁分别锁单行 / 锁开区间 / 锁左开右闭区间;RR 下临键锁是防幻读的关键
唯一索引等值查询的加锁记录存在时退化为记录锁,不存在时退化为间隙锁
插入意向锁插入前加的间隙锁特例,多个插入同一间隙互不阻塞
死锁循环等待;MySQL 会自动检测并回滚代价较小的事务,报 Deadlock found
避免死锁的办法按固定顺序访问资源、缩短事务、减少无索引更新、把大事务拆小
SHOW ENGINE INNODB STATUS看最近一次死锁的现场(两个事务的 SQL 与持锁等待关系)
锁等待超时innodb_lock_wait_timeout 默认 50 秒,超时报错而不是死锁
元数据锁 MDLDDL 与 DML 之间的互斥锁,长事务会让 ALTER TABLE 一直等,进而阻塞后续所有查询

六、日志与持久化

术语一句话释义
redo logInnoDB 的物理日志,循环写、保证崩溃后能重放已提交修改(持久性 D)
undo log逻辑日志,记录反向操作,用于回滚与 MVCC(原子性 A)
binlogServer 层的逻辑日志,记录所有变更,用于主从复制与数据恢复
WAL(预写日志)先写日志再写数据页,把随机写变成顺序写,这是 InnoDB 高性能的关键
两阶段提交 2PCredo 写 prepare → binlog 写 → redo 写 commit,保证两份日志一致
组提交 Group Commit多个事务共享一次 fsync,显著提升写入吞吐
innodb_flush_log_at_trx_commit1 最安全(每次提交刷盘),0/2 性能好但可能丢数据
sync_binlog为 1 时每次提交刷 binlog,金融场景通常要求 1+1(双 1 配置)
CRASH-SAFE 恢复流程启动时先看 redo 里 prepare 且 binlog 完整的就提交,否则回滚
日志相关排查磁盘被 binlog 打满很常见,靠 expire_logs_days/binlog_expire_logs_seconds 与备份策略控制

七、主从复制与高可用

术语一句话释义
主从复制原理主库写 binlog → 从库 IO 线程拉取写 relay log → SQL 线程回放
异步复制主库提交即返回,主库宕机会丢未同步的数据
半同步复制至少一个从库确认收到才返回,兼顾安全与性能
组复制 MGR / MGR 单主模式基于 Paxos 变体的多副本一致性方案,支持自动选主
GTID全局事务 ID,替代 binlog 文件名+位置,故障切换后易定位断点
主从延迟大事务、从库单线程回放(5.7+ 支持并行回放)、从库负载高都会导致延迟
延迟的排查SHOW SLAVE STATUS 看 Seconds_Behind_Master 与 Retrieved/Executed_Gtid_Set
读己之写主从架构下的经典一致性问题:写后立刻读从库可能读不到,解法是写后一段时间强制走主库
MHA / Orchestrator / ProxySQL常见高可用与读写分离中间件
备份方式逻辑备份 mysqldump(小库)vs 物理备份 XtraBackup(大库、可增量)
恢复演练备份只有被验证过能恢复才算备份;「备份存在但恢复失败」是最常见事故

参考资料