浅谈MySql之中的引擎

包含MySql之中的索引以及B+树的实现

Posted by Haiming on July 9, 2019

作为一款被广泛使用的数据库,MySql在很多的地方都有使用。今天在这里主要是针对其中的数据库引擎,包括不同引擎的锁的力度,还有MySql之中的索引技术进行一点简要的分析和总结。

下面是参考文章链接:

https://blog.csdn.net/zgrgfr/article/details/74455547

https://zhuanlan.zhihu.com/p/42106761

一、存储引擎

MySql 之中有几种存储引擎,其中最常使用的是 MyISAM 和 InnoDB。下面就这两种主要的引擎进行介绍和比较。在 MySql 5.5 之前,其默认引擎是 MyISAM, 自 5.5 之后,其默认引擎是 InnoDB。

1.0 主要区别简述

  1. InnoDB 支持外键和事务,对于 InnoDB 而言,每一条 SQL 语句都默认封装成事务之后提交。但是 MyISAM 不支持外键和事务。

  2. MySql 之中每个表都有一个聚焦索引(clustered index),初次之外表上的每一个其他索引都是二级索引,又叫辅助索引(secondary indexes)

    InnoDB 是聚焦索引(clustered index),数据文件和索引捆绑在一起,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,第一步是得到主键,第二步才是通过主键查询到数据。因此主键不应该过大。

    MyISAM 是非聚焦索引, 数据和文件是分离的,索引保存的只是数据的指针。主键索引和辅助索引是独立的。

  3. 锁的粒度不同。这一点下面会具体讲述。

  4. InnoDB 不保存表的具体行数,如果执行语句select count(*) from table ,需要全表重新扫描一遍。但是 MyISAM 之中有一个变量保存了整个表的行数,执行上述语句只要读取这个变量即可。

  5. InnoDB 不支持全文索引,但是 MyISAM 支持全文索引,查找效率上面 MyISAM 更高。

1.1 MyISAM 存储引擎

MyISAM 有较高的插入和查询速度,但是不支持事务

MyISAM 使用 B+ 树作为存储结构,叶子节点之中的 data 域存放的是数据记录的地址。下面是原理图:

MyISAM

假设这个表一共有三个 column, 假设我们以 Col1 作为主键,上图即为 MyISAM 表的一个主索引 (Primary key) 示意。可以看到 MyISAM 之中保存的仅仅是数据记录的地址而不是数据本身 (例如15仅仅保存了 0x07 这个地址)。

在MyISAM 之中,主索引和辅助索引在结构上没有任何区别,只是主索引要求 key 唯一,但是辅助索引的 key 可以重复。 如果我们在 Col2 上建立一个辅助索引,那么索引的结构类似下图所示:

MyISAM

可见其中保存的仍然是记录的地址。

MyISAM 之中索引检索的算法为首先按照 B+树搜索算法搜索索引,如果指定的 key 存在,就取出 data 的值。然后将 data 作为地址,读取相应的数据记录。

MyISAM 之中的索引方式也被成为“非聚集”的,这种称呼是为了和 InnoDB 的聚集索引相区分。

1.2 InnoDB 存储引擎

InnoDB 是事务型数据库的首选引擎,支持事务安全表,支持行锁定外键(对比上面的 MyISAM 支持表锁定,不支持外键)。

InnoDB 的主要特性有:

  1. InnoDB给 MySql 提供了具有提交,回滚和崩溃恢复能力的事务安全存储引擎。

    InnoDB 之中的锁的级别在行级

    SELECT 之中提供的是非锁定读。

  2. InnoDB 将其表和索引放在一个逻辑表空间之中(MyISAM 之中的表和索引是分开存放,索引之中存放真实数据的地址),且表空间可以包含数个文件(MyISAM 表之中的每个表被放在分离的文件之中)。

InnoDB 也是使用 B+ 树作为索引结构。那么主要的区别在哪呢?

第一个区别是InnoDB的数据文件本身也就是索引文件。

在 MyISAM 之中的索引文件和数据文件是分离的,索引文件只保存数据记录的地址。但是在 InnoDB 之中,表数据文件本身就是按照 B+ 树组织的一个索引结构,这个树的叶节点 data 保存了完整的数据记录。这个索引的 key 是数据表的主键,所以 InnoDB 文件本身就是主索引。举个例子:

InnoDB

可以看到上面的叶子节点保存了完整的数据记录,这种方式就是上面提到过的聚集索引(clustered index) 。因为 InnoDB 本身要按主键聚集,所以 InnoDB 要求表必须有主键(MyISAM 可以没有,InnoDB 如果不指定主键那么会自动选择一列或者生成一个隐含字段)

第二个不同点在于 InnoDB 之中的辅助索引的 data 域记录的是主键的值而不是数据本身的地址。

换句话,InnoDB 之上的所有辅助索引都使用主键作为 data 域。如图:

InnoDB辅助索引

1.3 小结

  1. InnoDB 支持事务(transaction), 但是 MyISAM 不支持。
  2. InnoDB 支持行级锁, MyISAM 支持表级锁。
  3. InnoDB 支持外键,MyISAM 不支持。

要提供 提交回滚,崩溃回复能力的事务安全能力,并且要求 并发控制, InnoDB 是一个好的选择。

主要用来插入和查询记录,那么 MyISAM 可以提供较高的处理效率。

2. B+ 树(留坑待填 😀)