数据库面试题常问详细总结

数据库面试题常问详细总结

以下为数据库(以 MySQL 为主)面试中出现频率最高的知识点,按模块整理,每个题目均给出简洁、完整的回答,适合面试前快速复习。


目录

  • 一、事务(ACID、隔离级别、传播行为)
    • [1. 什么是事务?事务的 ACID 特性是什么?](#1. 什么是事务?事务的 ACID 特性是什么?)
    • [2. 事务的隔离级别有哪些?分别解决什么问题?](#2. 事务的隔离级别有哪些?分别解决什么问题?)
    • [3. MySQL 默认隔离级别是什么?如何修改?](#3. MySQL 默认隔离级别是什么?如何修改?)
  • 二、索引(B+树、聚集索引、回表、索引失效、最左匹配)
    • [4. 什么是索引?有哪些优缺点?](#4. 什么是索引?有哪些优缺点?)
    • [5. B+树索引与 Hash 索引的区别?为什么 InnoDB 使用 B+树?](#5. B+树索引与 Hash 索引的区别?为什么 InnoDB 使用 B+树?)
    • [6. 聚集索引与非聚集索引的区别?](#6. 聚集索引与非聚集索引的区别?)
    • [7. 什么是回表?如何减少回表?](#7. 什么是回表?如何减少回表?)
    • [8. 什么是最左匹配原则?](#8. 什么是最左匹配原则?)
    • [9. 索引失效的常见情况有哪些?](#9. 索引失效的常见情况有哪些?)
    • [10. 什么时候应该/不应该创建索引?](#10. 什么时候应该/不应该创建索引?)
  • [三、存储引擎(InnoDB vs MyISAM)](#三、存储引擎(InnoDB vs MyISAM))
    • [11. InnoDB 和 MyISAM 的主要区别?](#11. InnoDB 和 MyISAM 的主要区别?)
    • [12. 如何选择存储引擎?](#12. 如何选择存储引擎?)
  • 四、锁机制(悲观锁、乐观锁、行锁、表锁、间隙锁)
    • [13. 什么是悲观锁和乐观锁?](#13. 什么是悲观锁和乐观锁?)
    • [14. InnoDB 的行锁、表锁、间隙锁是什么?](#14. InnoDB 的行锁、表锁、间隙锁是什么?)
    • [15. 什么是死锁?如何避免?](#15. 什么是死锁?如何避免?)
  • [五、SQL 优化(Explain、慢查询、分页优化)](#五、SQL 优化(Explain、慢查询、分页优化))
    • [16. 如何定位并优化慢查询?](#16. 如何定位并优化慢查询?)
    • [17. 如何优化深分页(如 LIMIT 100000, 10)?](#17. 如何优化深分页(如 LIMIT 100000, 10)?)
    • [18. COUNT(*)、COUNT(1)、COUNT(列) 有什么区别?](#18. COUNT(*)、COUNT(1)、COUNT(列) 有什么区别?)
    • [19. UNION 和 UNION ALL 的区别?](#19. UNION 和 UNION ALL 的区别?)
  • 六、数据库架构(主从复制、读写分离、分库分表)
    • [20. 什么是主从复制?原理是什么?](#20. 什么是主从复制?原理是什么?)
    • [21. 读写分离如何实现?](#21. 读写分离如何实现?)
    • [22. 什么是分库分表?有哪些策略?](#22. 什么是分库分表?有哪些策略?)
  • 七、其他高频考点
    • [23. 三大范式是什么?](#23. 三大范式是什么?)
    • [24. 什么是视图?有什么优缺点?](#24. 什么是视图?有什么优缺点?)
    • [25. 什么是存储过程?优缺点?](#25. 什么是存储过程?优缺点?)
    • [26. 什么是触发器?](#26. 什么是触发器?)
    • [27. DELETE、TRUNCATE、DROP 的区别?](#27. DELETE、TRUNCATE、DROP 的区别?)
    • [28. CHAR 和 VARCHAR 的区别?](#28. CHAR 和 VARCHAR 的区别?)
    • [29. 什么是临时表?](#29. 什么是临时表?)
    • [30. 数据库连接池的作用?](#30. 数据库连接池的作用?)
  • [八、非关系型数据库(Redis / MongoDB 简要)](#八、非关系型数据库(Redis / MongoDB 简要))
    • [31. Redis 和 MySQL 的区别?](#31. Redis 和 MySQL 的区别?)
    • [32. 什么是缓存穿透、缓存击穿、缓存雪崩?](#32. 什么是缓存穿透、缓存击穿、缓存雪崩?)

一、事务(ACID、隔离级别、传播行为)

1. 什么是事务?事务的 ACID 特性是什么?

事务是一组原子性的操作,要么全部成功,要么全部失败。

  • 原子性:事务中的操作不可分割。
  • 一致性:事务前后数据完整性约束不被破坏。
  • 隔离性:多个事务并发执行时互不干扰。
  • 持久性:事务提交后数据永久保存。

2. 事务的隔离级别有哪些?分别解决什么问题?

隔离级别 脏读 不可重复读 幻读 说明
READ UNCOMMITTED 读未提交,性能最好,问题最多
READ COMMITTED 读已提交(Oracle默认)
REPEATABLE READ 可重复读(MySQL默认)
SERIALIZABLE 串行化,性能最差
  • 脏读:读到未提交的数据。
  • 不可重复读:同一事务内两次读取同一行数据结果不同(被其他事务修改)。
  • 幻读:同一事务内两次查询返回的记录数不同(被其他事务插入/删除)。

3. MySQL 默认隔离级别是什么?如何修改?

默认是 REPEATABLE READ。可通过 SET GLOBAL TRANSACTION ISOLATION LEVEL 修改。


二、索引(B+树、聚集索引、回表、索引失效、最左匹配)

4. 什么是索引?有哪些优缺点?

索引是帮助数据库高效获取数据的数据结构(如 B+树)。

  • 优点:加速查询,唯一索引保证唯一性。
  • 缺点:占用额外空间,降低增删改的速度。

5. B+树索引与 Hash 索引的区别?为什么 InnoDB 使用 B+树?

类型 优点 缺点
Hash 等值查询 O(1) 不支持范围查询、排序
B+树 支持范围、排序、稳定 等值查询略慢于 Hash

B+树优点

  • 树矮(3~4层可存千万数据),I/O 次数少。
  • 叶子节点有序链表,范围查询高效。
  • 非叶子节点只存索引,单页存储更多索引项。

6. 聚集索引与非聚集索引的区别?

  • 聚集索引(InnoDB):叶子节点存储完整行数据。主键就是聚集索引,表中数据按主键顺序存储。
  • 非聚集索引(MyISAM / InnoDB辅助索引):叶子节点存储主键值(或行指针),需要"回表"才能拿到完整数据。

7. 什么是回表?如何减少回表?

在 InnoDB 中,使用辅助索引查询时,先找到主键值,再根据主键去聚集索引查找完整行,这个过程叫回表
减少方法 :使用覆盖索引(索引中已包含所需字段,无需回表)。

8. 什么是最左匹配原则?

对于组合索引 (a, b, c),查询条件必须从最左列开始连续匹配,跳列会导致索引部分失效。

  • WHERE a = 1 AND b = 2 → 使用索引
  • WHERE b = 2 AND c = 3 → 不使用索引
  • WHERE a = 1 AND c = 3 → 仅使用 a 列索引
  • 优化器会自动调整 AND 顺序,但无法跳过第一列。

9. 索引失效的常见情况有哪些?

  • 使用 OR 且未对所有条件列分别建索引。
  • LIKE '%xxx'(以通配符开头)。
  • 对索引列使用函数或表达式(如 WHERE YEAR(date)=2020)。
  • 隐式类型转换(如字符串列 = 数字)。
  • IS NULL 可能失效(视优化器而定),IS NOT NULL 通常有效。
  • MySQL 认为全表扫描更快时(如小表或返回大量数据)。

10. 什么时候应该/不应该创建索引?

  • 应该:频繁查询、排序、分组的列;数据量大且查询选择性高的列。
  • 不应该:频繁更新的表;数据量小;列值重复度高(如性别);写入远多于读取的场景。

三、存储引擎(InnoDB vs MyISAM)

11. InnoDB 和 MyISAM 的主要区别?

特性 InnoDB MyISAM
事务 支持 不支持
锁粒度 行级锁 表级锁
外键 支持 不支持
崩溃恢复
全文索引 MySQL 5.6+ 支持 支持
适用场景 高并发写入、需要事务 读多写少、不需要事务

12. 如何选择存储引擎?

  • 需要事务、行锁、外键 → InnoDB
  • 读为主、写极少、可接受表锁 → MyISAM
  • 现在 MySQL 默认且推荐 InnoDB。

四、锁机制(悲观锁、乐观锁、行锁、表锁、间隙锁)

13. 什么是悲观锁和乐观锁?

  • 悲观锁 :假设会发生冲突,查询时加锁(如 SELECT ... FOR UPDATE),直到事务提交才释放。
  • 乐观锁:假设不会冲突,更新时通过版本号(version)检查,若版本不一致则重试或失败。

14. InnoDB 的行锁、表锁、间隙锁是什么?

  • 行锁:锁定索引记录,并发度高。
  • 表锁 :锁定整张表(如 LOCK TABLES)。
  • 间隙锁 :锁定索引记录之间的间隙,防止幻读(在 REPEATABLE READ 级别下,SELECT ... FOR UPDATE 或范围更新时会使用)。

15. 什么是死锁?如何避免?

死锁是两个或多个事务相互持有对方所需的锁。
避免方法

  • 统一访问表的顺序。
  • 缩短事务长度,及时提交。
  • 使用较低隔离级别。
  • 使用乐观锁代替悲观锁。

五、SQL 优化(Explain、慢查询、分页优化)

16. 如何定位并优化慢查询?

  1. 开启慢查询日志,设置 long_query_time
  2. 使用 EXPLAIN 分析执行计划,关注 typeALL 全表扫描最差)、key(实际使用的索引)、rows(扫描行数)、ExtraUsing filesortUsing temporary 需优化)。
  3. 根据分析结果:添加或调整索引、重写 SQL、避免函数/隐式转换。
  4. 考虑业务层面优化(如分页、缓存)。

17. 如何优化深分页(如 LIMIT 100000, 10)?

  • 使用子查询先获取起始主键:SELECT * FROM t WHERE id >= (SELECT id FROM t ORDER BY id LIMIT 100000,1) LIMIT 10
  • 使用延迟关联:先查索引列,再回表。
  • 记录上次查询的最大值,下一页用 WHERE id > last_max LIMIT 10
  • 禁止跳页,只提供"上一页/下一页"。

18. COUNT(*)COUNT(1)COUNT(列) 有什么区别?

  • COUNT(*)COUNT(1) 结果相同,统计所有行(包括 NULL)。
  • COUNT(列) 统计该列非 NULL 的行数。
  • 在 InnoDB 中,COUNT(*) 需要扫描索引或表,没有直接存储总数。

19. UNIONUNION ALL 的区别?

  • UNION 去重并排序,效率低。
  • UNION ALL 不去重,直接合并,效率高。
  • 若无重复需求,优先用 UNION ALL

六、数据库架构(主从复制、读写分离、分库分表)

20. 什么是主从复制?原理是什么?

主库将数据变更写入二进制日志(binlog),从库通过 I/O 线程读取 binlog 并写入中继日志,再由 SQL 线程重放。
用途:读写分离、数据备份、负载均衡、高可用。

21. 读写分离如何实现?

  • 应用层:配置多个数据源,通过 AOP(如注解)判断读写操作,写走主库,读走从库。
  • 中间件:如 MyCat、ShardingSphere-JDBC。
  • 注意主从延迟问题(刚写入后立即读可能读不到)。

22. 什么是分库分表?有哪些策略?

  • 垂直分表:把宽表拆成多个小表(如将不常访问的字段分离)。
  • 垂直分库:按业务模块拆分数据库。
  • 水平分表:按某个字段(如用户ID)取模、范围、哈希等将数据分散到多张表。
  • 水平分库:将数据分散到多个数据库实例。
  • 常用中间件:ShardingSphere、MyCat、TDDL。

七、其他高频考点

23. 三大范式是什么?

  • 1NF:字段不可再分。
  • 2NF:在 1NF 基础上,非主键字段完全依赖主键(消除部分依赖)。
  • 3NF:在 2NF 基础上,非主键字段之间不传递依赖。

24. 什么是视图?有什么优缺点?

视图是虚拟表,基于 SELECT 语句。
优点 :简化查询、安全(隐藏敏感列)、逻辑独立性。
缺点:查询性能可能下降,部分视图不可更新。

25. 什么是存储过程?优缺点?

存储过程是预编译的 SQL 集合。
优点 :封装业务、减少网络传输、执行快。
缺点:数据库迁移困难、业务逻辑与数据库耦合、调试麻烦。

26. 什么是触发器?

触发器是自动执行的存储过程,由 INSERT、UPDATE、DELETE 事件触发。
用途 :审计日志、数据校验、级联更新。
注意:滥用触发器会导致逻辑复杂、难以排查。

27. DELETETRUNCATEDROP 的区别?

操作 类型 可否回滚 空间 定义 速度
DELETE DML 可回滚 不释放 保留 慢(逐行)
TRUNCATE DDL 不可回滚 释放 保留
DROP DDL 不可回滚 全部释放 删除 最快

28. CHARVARCHAR 的区别?

  • CHAR(n) 固定长度,最大 255,会填充空格,适合长度固定的数据(如身份证)。
  • VARCHAR(n) 可变长度,最大 65535 字节,节省空间,适合长度变化大的数据。

29. 什么是临时表?

临时表只在当前会话或事务中可见,会话结束自动删除。用于复杂查询的中间结果暂存。

30. 数据库连接池的作用?

  • 减少连接创建/销毁开销。
  • 限制最大连接数,防止资源耗尽。
  • 提高响应速度。

八、非关系型数据库(Redis / MongoDB 简要)

31. Redis 和 MySQL 的区别?

  • MySQL 是磁盘关系型数据库,支持 SQL 和事务。
  • Redis 是内存键值存储,支持丰富数据结构(String、Hash、List、Set、ZSet),读写极快,适合缓存、会话、计数器等。

32. 什么是缓存穿透、缓存击穿、缓存雪崩?

  • 穿透:查询不存在的数据,请求直接打到 DB。解决:布隆过滤器、缓存空值。
  • 击穿:热点 key 过期,大量并发重建缓存。解决:互斥锁、永不过期。
  • 雪崩:大量 key 同时过期,DB 压力骤增。解决:随机过期时间、高可用集群。

相关推荐
爱学习的小邓同学2 小时前
MySQL --- MySQL库和表的操作
数据库·mysql
m0_493934532 小时前
TensorFlow如何监控内存使用情况_结合tf.summary记录关键指标信息
jvm·数据库·python
以神为界2 小时前
数据库入门全指南:从基础概念到实操操作(含SQL+Navicat)
网络·数据库·sql·安全
Elastic 中国社区官方博客2 小时前
Elasticsearch:快速近似 ES|QL - 第二部分
大数据·数据库·sql·elasticsearch·搜索引擎·全文检索
Polar__Star2 小时前
Go语言中--=运算符详解:位右移赋值操作的原理与实践
jvm·数据库·python
qq_189807032 小时前
Navicat导出JSON数据为空如何解决_过滤条件与权限排查
jvm·数据库·python
2301_813599552 小时前
HTML表单能嵌套吗_表单嵌套限制与替代方案【解答】
jvm·数据库·python
CesareCheung2 小时前
SonarQube安装下载及代码覆盖率使用
数据库·代码覆盖率
yejqvow122 小时前
如何使用可视化查询生成器_免敲代码的多表JOIN配置
jvm·数据库·python