SQL面试高频问题_数据库基础知识总结

4次阅读

事务是不可分割的操作单元,acid 通过 undo log(原子性)、约束与逻辑(一致性)、锁 /mvcc(隔离性)、redo log(持久性)保障;inner join 仅返回匹配行,left join 保留左表全部记录;主键唯一非空且建聚簇索引,唯一索引允许 null,普通索引仅加速查询;count(*) 统计所有行且最快,count(字段) 仅计非 null 值。

SQL 面试高频问题_数据库基础知识总结

SQL 面试中,数据库基础知识是必考内容,重点不在死记硬背语法,而在于理解底层逻辑和实际场景的应对能力。以下从四个高频维度梳理核心要点,覆盖概念辨析、查询逻辑、数据完整性与性能意识。

什么是事务?ACID 怎么保证的?

事务是一组不可分割的操作单元,典型场景如银行转账:扣款和入账必须同时成功或同时失败。ACID 是它的四个关键特性:

  • 原子性(Atomicity):靠 undo log 实现回滚,任一语句失败,整个事务撤销
  • 一致性(Consistency):由应用逻辑 + 约束(如外键、CHECK)共同保障,数据库本身不自动“保证业务一致”
  • 隔离性(Isolation):通过锁机制或 MVCC 控制并发读写,常见隔离级别有 READ UNCOMMITTED 到 SERIALIZABLE
  • 持久性(Durability):靠 redo log 确保崩溃后可恢复,提交后的数据不会丢失

面试常问“脏读、不可重复读、幻读分别发生在哪个隔离级别?”——本质是考察对 MVCC 和锁行为的理解,不是背级别名称。

INNER JOIN 和 LEFT JOIN 的区别到底在哪?

关键看驱动表(左表)的记录是否全部保留:

  • INNER JOIN:只返回左右表都能匹配上的行,不匹配的行全被过滤
  • LEFT JOIN:以左表为基准,左表每行都出现;右表无匹配时,对应字段为 NULL

易错点:WHERE 条件写在 JOIN 之后会把 LEFT JOIN“变相转成 INNER JOIN”。例如 SELECT * FROM A LEFT JOIN B ON A.id = B.a_id WHERE B.status = ‘active’——B 无匹配时 B.status 为 NULL,不满足 WHERE,结果等效于 INNER JOIN。正确做法是把过滤条件放到 ON 子句中:ON A.id = B.a_id AND B.status = ‘active’

主键、唯一索引、普通索引的区别和使用场景

三者都可用于加速查询,但约束能力和设计意图不同:

  • 主键(PRIMARY KEY):唯一 + 非空 + 自动创建聚簇索引(InnoDB),一张表只能有一个
  • 唯一索引(UNIQUE INDEX):唯一 + 允许 NULL(注意:多个 NULL 不算重复),适合业务上要求唯一的字段,如手机号、邮箱
  • 普通索引(INDEX):仅加速查询,不约束数据,适合高频 WHERE 或 ORDER BY 字段,如 create_time、status

补充:联合索引遵循最左前缀原则。比如 (index_a_b_c),能命中 a =1、a=1 AND b=2、a=1 AND b=2 AND c=3,但不能命中 b = 2 或 c = 3 单独查询。

为什么 COUNT(*) 比 COUNT(字段) 快?NULL 值怎么影响统计?

COUNT 函数统计的是行数,但语义不同:

  • COUNT(*):统计所有行,包括含 NULL 的行,优化器通常直接读取元数据或聚簇索引行数,无需查字段内容
  • COUNT(字段):只统计该字段非 NULL 的行数,需逐行判断字段值是否为 NULL,开销更大
  • COUNT(1):和 COUNT(*) 基本等价,都是统计行数,现代 MySQL 优化器已无实质差异

特别注意:COUNT(id) 如果 id 是主键,也等价于 COUNT(*);但如果 id 允许 NULL,那 COUNT(id) 就只算非空 id 的行数——这点常被忽略。

text=ZqhQzanResources