1. 请说下你对 MySQL 架构的了解?
� 先看下 MySQL 的基本架构图:
大体来说,MySQL 可以分为 Server 层和存储引擎两部分。
Server 层包括:连接器、查询缓存、分析器、优化器、执行器等,涵盖了 MySQL
的大多数核心服务功能,以及所有的内置函数(如:日期、时间、数学和加密函数
等),所有跨存储引擎的功能都在这一层实现,比如:存储过程、触发器、视图等等。
存储引擎层负责:数据的存储和提取。其架构是插件式的,支持 InnoDB、MyISAM
等多个存储引擎。从 MySQL5.5.5 版本开始默认的是 InnoDB,但是在建表时可以
通过 engine = MyISAM 来指定存储引擎。不同存储引擎的表数据存取方式不同,支
持的功能也不同。
从上图中可以看出,不同的存储引擎共用一个 Server 层,也就是从连接器到执行器的
部分。
2. 一条 SQL 语句在数据库框架中的执行流程?
应用程序把查询 SQL 语句发送给服务器端执行;
查询缓存,如果查询缓存是打开的,服务器在接收到查询请求后,并不会直接去数据库查询,
而是在数据库的查询缓存中找是否有相对应的查询数据,如果存在,则直接返回给客户端。
只有缓存不存在时,才会进行下面的操作;
查询优化处理,生成执行计划。这个阶段主要包括解析 SQL、预处理、优化 SQL 执行计划;
MySQL 根据相应的执行计划完成整个查询;
将查询结果返回给客户端。
3. 数据库的三范式是什么?
第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项;
第二范式:要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键
字一部分的属性;
第三范式:任何非主属性不依赖于其它非主属性。
4. char 和 varchar 的区别?
char(n) :固定长度类型,比如:订阅 char(10),当你输入”abc”三个字符的时候,它们占
的空间还是 10 个字节,其他 7 个是空字节。char 优点:效率高;缺点:占用空间;适用
场景:存储密码的 md5 值,固定长度的,使用 char 非常合适。
varchar(n) :可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的
长度。
所以,从空间上考虑 varcahr 比较合适;从效率上考虑 char 比较合适,二者使用需要权衡。
5. varchar(10) 和 varchar(20) 的区别?
varchar(10) 中 10 的涵义最多存放 10 个字符,varchar(10) 和 varchar(20)
存储 hello 所占空间一样,但后者在排序时会消耗更多内存,因为 order by col 采
用 fixed_length 计算 col 长度
6. 谈谈你对索引的理解?
索引的出现是为了提高数据的查询效率,就像书的目录一样。一本 500 页的书,如果你想快
速找到其中的某一个知识点,在不借助目录的情况下,那我估计你可得找一会儿。同样,对
于数据库的表而言,索引其实就是它的“目录”。
同样索引也会带来很多负面影响:创建索引和维护索引需要耗费时间,这个时间随着数据量
的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用
物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速
度。
建立索引的原则:
在最频繁使用的、用以缩小查询范围的字段上建立索引;
在频繁使用的、需要排序的字段上建立索引。
不适合建立索引的情况:
对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引;
对于一些特殊的数据类型,不宜建立索引,比如:文本字段(text)等
7. 索引的底层使用的是什么数据结构?
索引的数据结构和具体存储引擎的实现有关,,在 MySQL 中使用较多的索引有 Hash
索引、B+树索引等。而我们经常使用的 InnoDB 存储引擎的默认索引实现为 B+ 树
索引。
8. 谈谈你对 B+ 树的理解?
B+ 树是基于 B 树和叶子节点顺序访问指针进行实现,它具有 B 树的平衡性,并且通过顺
序访问指针来提高区间查询的性能。
在 B+ 树中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别
是 key i 和 key i+1,且不为 null,则该指针指向节点的所有 key 大于等于 key i 且小于等
于 key i+1。
进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在
指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出
key 所对应的 data。
插入、删除操作会破坏平衡树的平衡性,因此在插入删除操作之后,需要对树进行一个分裂、
合并、旋转等操作来维护平衡性。
9. 为什么 InnoDB 存储引擎选用 B+ 树而不是 B 树呢?
用 B+ 树不用 B 树考虑的是 IO 对性能的影响,B 树的每个节点都存储数据,而 B+
树只有叶子节点才存储数据,所以查找相同数据量的情况下,B 树的高度更高,IO 更
频繁。数据库索引是存储在磁盘上的,当数据量大时,就不能把整个索引全部加载到内
存了,只能逐一加载每一个磁盘页(对应索引树的节点)。
MySQL 面试题
10. 谈谈你对聚簇索引的理解?
聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法。特点
是存储数据的顺序和索引顺序一致。一般情况下主键会默认创建聚簇索引,且一张表只
允许存在一个聚簇索引。
聚簇索引和非聚簇索引的区别:
聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过
有指向对应数据块的指针。
11. 谈谈你对哈希索引的理解?
哈希索引能以 O(1) 时间进行查找,但是失去了有序性。无法用于排序与分组、只支
持精确查找,无法用于部分查找和范围查找。
InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非
常频繁时,会在 B+ 树索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈
希索引的一些优点,比如:快速的哈希查找。
12. 谈谈你对覆盖索引的认识?
如果一个索引包含了满足查询语句中字段与条件的数据就叫做覆盖索引。具有以下优点:
索引通常远小于数据行的大小,只读取索引能大大减少数据访问量。
一些存储引擎(例如:MyISAM)在内存中只缓存索引,而数据依赖于操作系统来缓存。因
此,只访问索引可以不使用系统调用(通常比较费时)。
对于 InnoDB 引擎,若辅助索引能够覆盖查询,则无需访问主索引。
13. 索引的分类?
从数据结构角度
树索引 (O(log(n)))
Hash 索引
从物理存储角度
聚集索引(clustered index)
非聚集索引(non-clustered index)
从逻辑角度
普通索引
唯一索引
主键索引
联合索引
全文索引
14. 谈谈你对最左前缀原则的理解?
MySQL 使用联合索引时,需要满足最左前缀原则。下面举例对其进行说明:
1. 一个 2 列的索引 (name, age),对 (name)、(name, age) 上建立了索引;
2. 一个 3 列的索引 (name, age, sex),对 (name)、(name, age)、(name, age, sex) 上建立了
索引。
Java
1、 B+ 树的数据项是复合的数据结构,比如:(name, age, sex) 的时候,B+ 树是按照从左
到右的顺序来建立搜索树的,比如:当(小明, 22, 男)这样的数据来检索的时候,B+ 树会优
先比较 name 来确定下一步的所搜方向,如果 name 相同再依次比较 age 和 sex,最后得
到检索的数据。但当 (22, 男) 这样没有 name 的数据来的时候,B+ 树就不知道第一步该
查哪个节点,因为建立搜索树的时候 name 就是第一个比较因子,必须要先根据 name 来
搜索才能知道下一步去哪里查询。
2、 当 (小明, 男) 这样的数据来检索时,B+ 树可以用 name 来指定搜索方向,但下一个
字段 age 的缺失,所以只能把名字等于小明的数据都找到,然后再匹配性别是男的数据了,
这个是非常重要的性质,即索引的最左匹配特性。
关于最左前缀的补充:
最左前缀匹配原则会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,