天天看点

MySQL面试知识点

数据库面试

1. 存储模块

存储管理、缓存机制、SQL解析、日志管理、权限划分、容灾机制、索引管理、锁管理

MySQL面试知识点

2. 索引模块

2.1 为什么使用索引

a.加快查询速度,提高系统的性能

b.通过创建唯一性索引,可以保证数据库表行数据的唯一性

2.2 MySQL索引的使用

索引在MYSQL中使用分为以下几类:

a. B+ -Tree索引

b. Hash索引

c. 全文索引

开发中最常接触到的 InnoDB 存储引擎中的 B+ 树索引.要介绍 B+ 树索引,就不得不提二叉查找树,平衡二叉树和 B 树这三种数据结构。B+ 树就是从他们仨演化来的。

此处二叉树和平衡二叉树不做解释,可以百度数据结构进行学习

B树结构图:

MySQL面试知识点

从上图可以看出,B树相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点,子节点的个数一般称为阶,上述图中的B 树为 3 阶 B 树,高度也会很低。

基于这个特性,B 树查找数据读取磁盘的次数将会很少,数据的查找效率也会比平衡二叉树高很多。

B+ 树

B+树是对B树的进一步优化。结果图如下:

MySQL面试知识点

a. B+树非叶子节点不存储数据,仅存储键值

b. 这样的话,非叶子节点会存储更多的键值,相应的数的阶数(叶子节点)就会更大,树的深度越小,进行磁盘IO的操作将减少,数据查询效率也会更快

c. B+树各个页之间是通过双向链表连接的,叶子节点中的数据是通过单向链表连接的,因此数据是有序的,方便范围查询

MyISAM 中的 B+ 树索引实现与 InnoDB 中的略有不同。在 MyISAM 中,B+ 树索引的叶子节点并不存储数据,而是存储数据的文件地址。

2.3 聚簇索引和非聚簇索引

a. 聚簇索引:以 InnoDB 作为存储引擎的表,表中的数据都会有一个主键,即使你不创建主键,系统也会帮你创建一个隐式的主键。

这是因为 InnoDB 是把数据存放在 B+ 树中的,而 B+ 树的键值就是主键,在 B+ 树的叶子节点中,存储了表中所有的数据。

这种以主键作为 B+ 树索引的键值而构建的 B+ 树索引,我们称之为聚集索引。

b. 非聚簇索引:以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。

非聚集索引与聚集索引的区别在于非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。

在 MyISAM 中,聚集索引和非聚集索引的叶子节点都会存储数据的文件地址。

2.4 Hash索引

在MySQL的存储引擎中,MyISAM不支持哈希索引,而InnoDB中的hash索引是存储引擎根据B-Tree索引自建的

1、hash索引是基于hash表实现的,只有查询条件精确匹配hash索引中的所有列的时候,才能用到hash索引。

2、对于hash索引中的所有列,存储引擎都会为每一行计算一个hash码,hash索引中存储的就是hash码。

3、hash索引包括键值、hash码和指针 。

Hash索引查询效率高于B+ -tree,但只能精确查询,因为每个hash值之间没有关系,因此不能进行排序和范围查询

2.5 索引越多越好吗?

a. 对于数据少的表数据,不使用索引,系统开销小 多索引

b. 需要多维护,占用额外空间

3. 如何定位并优化慢查询Sql

a. 根据慢日志定位慢查询sql

b. 使用explain工具分析sqll

c. 修改sql或者让sql走索引

4.锁模块

4.1 MyISAM与InnoDB关于锁方面的区别是什么

MyISAM默认使用表锁,而InnoDB默认使用行锁,同时也支持表锁。

在MySQL中某个事物打开共享读锁,进行读操作,其他事物进行写操作是不受影响的,因读锁起到共享的作用。而此事物 打开写锁进行写操作,其他事物进行读操作会进入阻塞状态,直至排它锁释放。

4.1.1 表锁和行锁的区别
表锁:锁表快、开销小、锁的粒度大,并发处理能力低,发生锁冲突概率高,不会出现死锁现象
行锁:锁表慢、开销大、锁的粒度小、并发处理能力高,发生锁冲突的概率低,会出现死锁现象

4.1.2 悲观锁和乐观锁
悲观锁:每次拿数据都会认为别人会修改,所以每次在拿数据前都会上锁,这样别人想拿这个数据就会阻塞,直至他获得锁资源,共享资源每次将提供给一个线程其他线程进入阻塞状态,用完后则会将资源转让给其他线程。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
 乐观锁:每次拿数据都会认定别人不会修改,所以不会上锁,但是在更新的时候会判断在此期间没有有人修改这个数据,可以使用版本号机制和CAS算法实现。适用于多读的应用场景,这样可以提高吞吐量。
           

5. 数据库事务的四大特性(ACID)

原子性:事务是数据库的最小工作单位,不可分割,因此事务包含的多个操作要么全部失败或者成功

一致性:事务执行前后要保持一致

隔离性: 多个事务之间互不影响,及一个事务内部对数据的操作对于其他事务是隔离的,不受其他事务的影响

持久性:事务一旦提交,他对数据库的中的数据的该表是持久化的,并且不能回滚

5.1 事务隔离级别以及各级别出现的问题

事务在并发访问下会出现的问题:更新丢失、脏读、不可重复的、幻读
事务隔离级别:读未提交、读以提交、可重复读、序列化

更新丢失:在并发场景下,两个事务修改同一数据导致后边修改数据覆盖前边修改的数据,破坏了事务的一致性原则,从而导致数据丢失
将数据库事务的隔离级别设置为读未提交,会解决更新丢失的问题,但会出现脏读、不可重复的、幻读现象

脏读:在并发场景下,一个事务读取到另一个事务没有提交的数据,读取到了脏数据,从而导致读取的数据不正确
将数据库事务隔离级别设置为读以提交,会解决脏读问题,但会出现不可重复的、幻读现象

不可重复读:在并发场景下,一个事务读取到另外一个事务提交的数据,导致两次读取不一致
将数据库事务隔离级别设置为可重复读, 会解决不可重复读问题,但会出现幻读现象

幻读:在并发场景下,一个事务读取到另一个事务加入或删除的数据,导致多读或少读的现象
将数据库事务隔离级别设置为序列化, 会解决幻读问题及其他问题,序列化是数据库事务最高的隔离级别
           

延伸问题:InnoDB可重复读隔离级别下如何避免幻读

详情