MySQL存储引擎MyISAM和InnoDB底层索引结构

深入理解MySQL索引底层数据结构与算法 (各种索引结构优缺点)

Myisam和Innodb索引实现的不同(存储结构)

存储引擎作用于什么对象

存储引擎是作用在表上的,而不是数据库。

MyISAM和InnoDB对索引和数据的存储在磁盘上是如何体现的

先来看下面创建的两张表信息,role表使用的存储引擎是MyISAM,而user使用的是InnoDB:

再来看下两张表在磁盘中的索引文件和数据文件:

1. role表有三个文件,对应如下:

role.frm:表结构文件
role.MYD:数据文件(MyISAM Data)
role.MYI:索引文件(MyISAM Index)

2. user表有两个文件,对应如下:

user.frm:表结构文件
user.ibd:索引和数据文件(InnoDB Data)
也由于两种引擎对索引和数据的存储方式的不同,我们也称MyISAM的索引为非聚集索引,InnoDB的索引为聚集索引。

InnoDB 索引文件和数据文件是一个;MyISAM索引文件和数据文件是分开的。

MyISAM主键索引与辅助索引的结构

我们先列举一部分数据出来分析,如下:

上面已经说明了MyISAM引擎的索引文件和数据文件是分离的,我们接着看一下下面两种索引结构异同。

主键索引

上一篇文章已经介绍过数据库索引是采用B+Tree存储,并且只在叶子节点存储数据,在MyISAM引擎中叶子结点存储的数据其实是索引和数据的文件指针两类。

如下图中我们以Col1列作为主键建立索引,对应的叶子结点储存形式可以看一下表格。

过索引查找数据的流程:先从索引文件中查找到索引节点,从中拿到数据的文件指针,再到数据文件中通过文件指针定位了具体的数据。

辅助(非主键)索引

以Col2列建立索引,得到的辅助索引结构跟上面的主键索引的结构是相同的。

在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。

InnoDB主键索引与辅助索引的结构

虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。

第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地 址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据 表的主键,因此InnoDB表数据文件本身就是主索引。

主键索引

我们已经知道InnoDB索引是聚集索引,它的索引和数据是存入同一个.idb文件中的,因此它的索引结构是在同一个树节点中同时存放索引和数据,如下图中最底层的叶子节点有三行数据,对应于数据表中的Col1、Col2、Col3数据项。

上图是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

辅助(非主键)索引

第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。下图为定义在Col3上的一个辅助索引:

在最底层的叶子结点有两行数据,第一行的字符串是辅助索引,按照ASCII码进行排序,第二行的整数是主键的值。

这里以英文字符的ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

InnoDB索引结构需要注意的点

1. 数据文件本身就是索引文件

2. 表数据文件本身就是按B+Tree组织的一个索引结构文件

3. 聚集索引中叶节点包含了完整的数据记录

4. InnoDB表必须要有主键,并且推荐使用整型自增主键

正如我们上面介绍InnoDB存储结构,索引与数据是共同存储的,不管是主键索引还是辅助索引,在查找时都是通过先查找到索引节点才能拿到相对应的数据,如果我们在设计表结构时没有显式指定索引列的话,MySQL会从表中选择数据不重复的列建立索引,如果没有符合的列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,并且这个字段长度为6个字节,类型为整型。

那为什么推荐使用整型自增主键而不是选择UUID?

UUID是字符串,比整型消耗更多的存储空间;
在B+树中进行查找时需要跟经过的节点值比较大小,整型数据的比较运算比字符串更快速;
自增的整型索引在磁盘中会连续存储,在读取一页数据时也是连续;UUID是随机产生的,读取的上下两行数据存储是分散的,不适合执行where id > 5 && id < 20的条件查询语句。
在插入或删除数据时,整型自增主键会在叶子结点的末尾建立新的叶子节点,不会破坏左侧子树的结构;UUID主键很容易出现这样的情况,B+树为了维持自身的特性,有可能会进行结构的重构,消耗更多的时间。

为什么非主键索引结构叶子节点存储的是主键值?

保证数据一致性和节省存储空间,可以这么理解:商城系统订单表会存储一个用户ID作为关联外键,而不推荐存储完整的用户信息,因为当我们用户表中的信息(真是名称、手机号、收货地址···)修改后,不需要再次维护订单表的用户数据,同时也节省了存储空间。

总结

了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长 的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为 InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用 自增字段作为主键则是一个很好的选择。

MySQL存储引擎MyISAM和InnoDB,索引结构优缺点的更多相关文章

  1. MySQL存储引擎 - Myisam和Innodb

    Mysql有两种存储引擎:InnoDB与Myisam,下表是两种引擎的简单对比   MyISAM InnoDB 构成上的区别: 每个MyISAM在磁盘上存储成三个文件.第一个 文件的名字以表的名字开始 ...

  2. MySQL存储引擎MyISAM与InnoDB

    一. MySQL存储引擎MyISAM与InnoDB如何选择 MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用:MyISAM.InnoDB.MERGE.MEMORY(HEAP).B ...

  3. MySQL存储引擎MyISAM与InnoDB的优劣

    使用MySQL当然会接触到MySQL的存储引擎,在新建数据库和新建数据表的时候都会看到. MySQL默认的存储引擎是MyISAM,其他常用的就是InnoDB了. 至于到底用哪种存储引擎比较好?这个问题 ...

  4. MySQL存储引擎MyISAM与InnoDB区别总结整理

    在MySQL的 可重复读隔离级别 中,是解决了幻读的读问题的. 1. MySQL默认存储引擎的变迁 在MySQL 5.5之前的版本中,默认的搜索引擎是MyISAM,从MySQL 5.5之后的版本中,默 ...

  5. 170309、MySQL存储引擎MyISAM与InnoDB区别总结整理

    1.MySQL默认存储引擎的变迁 在MySQL 5.1之前的版本中,默认的搜索引擎是MyISAM,从MySQL 5.5之后的版本中,默认的搜索引擎变更为InnoDB. 2.MyISAM与InnoDB存 ...

  6. MySQL存储引擎 -- MyISAM 与 InnoDB 实现

    一.MyISAM索引实现MyISAM引擎使用B树作为索引结构,叶节点的data域存放的是数据记录的地址. MyISAM主键索引这里设表一共有三列,假设我们以Col1为主键,Col2为辅助索引.则下图是 ...

  7. MySQL存储引擎MyISAM与InnoDB的区别比较

    使用MySQL当然会接触到MySQL的存储引擎,在新建数据库和新建数据表的时候都会看到. MySQL默认的存储引擎是MyISAM,其他常用的就是InnoDB了. 至于到底用哪种存储引擎比较好?这个问题 ...

  8. MySQL存储引擎 -- MyISAM 与 InnoDB 理论对比

    MySQL常用的两种存储引擎一个是MyISAM,另一个是InnoDB.两种存储引擎各有各的特点. 1. 区别:(1)事务处理:MyISAM是非事务安全型的.-----而非事务型的系统,一般也称为数据仓 ...

  9. MySQL存储引擎MyISAM与InnoDB区别

    简单的表达.  MyISAM 是非事务的存储引擎.  innodb是支持事务的存储引擎.    innodb的引擎比较适合于插入和更新操作比较多的应用  而MyISAM 则适合用于频繁查询的应用    ...

随机推荐

  1. Linq Introduce

    Linq学习网址: http://www.java2s.com/Code/CSharp/LINQ/CatalogLINQ.htm

  2. Ambiguous mapping. Cannot map 'appController' method

    笔者最初的一套代码模板 import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; impo ...

  3. 【ARTS】01_29_左耳听风-201900527~201900602

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

  4. Cache数据库新增用户并分配权限(Caché)

    1.通过浏览器登录管理中心,Caché自带的客户端工具是网页的,访问地址:     http://localhost:57772/csp/sys/UtilHome.csp 2.选择功能链接:系统管理- ...

  5. Java基础——值传递

    值传递? 参数传递的值的拷贝,改变拷贝不影响原参数. 引用传递? 参数传递的是参数本身,改变形参,实参也改变. Java中是什么传递? Java中只有值传递 实际情况为什么不对呢? 1. 基本数据类型 ...

  6. uWSGI 漏洞复现(CVE-2018-7490)

    uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换.WSGI是一种Web服务器网关接口.它是一 ...

  7. Dart学习笔记

    一.数据类型 1. 字符串 和 数字 互转 // String 转为 int '); assert(one == ); // String 转为 double var onePointOne = do ...

  8. editor does not cantain a main type——解决

    editor does not cantain a main type 这个错误就是包名与路径不对

  9. css设置滚动条并显示或隐藏

    看效果,没有滚动条,超出div,开发中肯定不行. 有滚动条 最后就是想隐藏滚动条 代码 有滚动条并显示 <!DOCTYPE html> <html lang="en&quo ...

  10. SQL SERVER2014 加密 备份恢复 学习 (一)

    SQL 自2008(还是2005)之后,推出加密功能,可以一定程度上保护数据库的备份安全.以下测试环境为:sql server 2014主要目的:将备份的文件加密,在其它电脑上恢复时必须有证书和密钥才 ...