1. 前言

在校招或者社招面试中,无论你是 Java 后端、Cpp 后端、Python 后端,面试官都会详细地考察各种语法细节、框架知识,但是大多数候选人入职之后,都会体会到 "面试造火箭,上班拧螺丝"。面试时我们熟悉各种知识细节,入职后却发现大部分工作都是重复的 CRUD(Create - 增加,Retrieve - 查询,Update - 更新,Delete - 删除),这种现象其实很正常。后端开发的核心职责就是倒腾数据,面临的基础问题例如如何设计数据的存储结构并且选择合适的数据库进行存储,如何在各种限制条件下查询数据。当我们负责的系统非常庞大之后,还会面临如何解决分布式系统的数据一致性这类更复杂的问题。

总结来说,操作数据库是后端程序员的必备技能。数据库按照存储数据结构的方式,可以分为关系型数据库以及非关系型数据库。关系型数据库中数据都是以二维表的形式存储,最常用的数据库有 Oracle、MySQL,非关系型数据库中数据都是以结构化的形式存储,最常用的数据库有 Redis、MongoDB、Hbase 等。目前互联网一二线大厂的校招要求,MySQL 基本是必备技能,非关系性数据库例如 Redis 这类不是必考内容,当然掌握了会是锦上添花。

本小节中会介绍关于 MySQL 常见高频面试题,以及核心回答思路解析。

2. MyISAM 和 InnoDB

面试官提问: 介绍下 InnoDB 和 MyISAM 存储引擎的区别,以及具体的应用场景?

题目解析:

首先要明确存储引擎的定义:MySQL 提供不同的技术存储数据,这些技术使用不同的数据存储机制、索引建立方式、锁方式来完成数据的构建,这些技术统称为存储引擎。

MySQL Client 终端输入 show engines 可查看支持的存储引擎类型。

图片描述

MySQL 5.7 实验结果

如图可见 MySQL 至少支持 9 种存储引擎,而面试中最受关注的是 InnoDB 和 MyISAM 存储引擎,一般的面试场景是这样的:

在上图的实验结果中,我们会发现在 MySQL 的所有存储引擎中,只有 InnoDB 支持 Transaction(事务)、XA(分布式事务),其他引擎均不支持,关于事务的支持能力是需要强调的点。关于两种引擎之间的区别,可以按下表进行分点阐述。

InnoDB MyISAM
事务 支持,强调的是保持数据一致性的高级功能 不支持,强调的是性能,查询速度比 InnoDB 快
外键 支持 不支持
索引 使用聚集索引,索引文件和数据文件绑定 使用非聚集索引,索引文件和数据文件分开存储,索引中保存的是数据文件的指针
支持表级锁、行级锁;
行级锁粒度小,处理并发的能力更强
支持表级锁,用户在执行 insert、update、select、delete 时都会给表自动加锁,效率低
主键 表必须有唯一索引(例如用户规定 id 作为主键),没有的话会用默认隐藏列 row_id 作为唯一索引 没有要求
存储文件 在操作系统中的存储文件:
.frm:表定义文件
.ibd:数据文件
在操作系统中的存储文件:
.frm:表定义文件
.myd:数据文件
.myi:索引文件

在阐述完两种存储引擎的区别之后,再根据两者的特点,枚举一些使用场景:

  1. MyISAM 对于不支持事务并且存在大量 SELECT 的读场景比较合适;

  2. 如果业务代码中要支持事务,必须选择 InnoDB 存储引擎;

  3. 如果业务代码中要支持外键,必须选择 InnoDB 存储引擎;

  4. 例如对电商公司来说,大部分的业务情况是要支持事务回滚的,例如下单流程失败之后要回滚已有的 Insert 语句,并且数据并发量高,这种场景肯定都是选择 InnoDB,笔者在生产环境中从未看到使用 MyISAM 存储引擎,两者对比更侧重考察候选人的理论知识。

3. 小结

本章节介绍了 MySQL 中两种不同的数据存储引擎,面试官针对回答可能会涉及到一些扩展性的问题,例如当谈到 InooDB 对事务的支持时,面试官很可能转为考察候选人对事务的理解程度。上述提到了聚集索引和非聚集索引,面试官可能会特意考察这两种索引的实现区别。MySQL 的外键定义,枚举使用场景和案例。这些问题也是候选人需要掌握的知识点。