在数据库体系中,我们可以使用不同的存储引擎来存储数据,而绝大多数存储引擎都用二进制来存储数据,下面介绍Inno DB是如何存储数据的。

       在Inno DB存储引擎中,所有的数据都被存储在表空间中,表空间是存储引擎中最高的存储逻辑单元,在表空间下依次包含: 段(segement),区(extend),页(page)。 在同一个数据库实例的所有表空间都有相同的页(page)大小,默认情况下表空间都是16KB。不同的页大小也会导致分区大小的不同。

       如何存储表: 

       mysql使用innoDB存储表时,也会将表的定义与数据索引等信息分开存储。前者存储在.frm文件,后者存储在.idb文件。

       当我们用sql创建一张表test_frm的时候,会在磁盘的.datadir文件夹生成一个test_frm.frm的文件,这个文件包含了表结构的相关信息。

       InnoDB用于存储数据的文件总共分为两部分,一是系统表空间文件,包含iddata1,iddata2等文件。其中存储了InnoDB系统信息和用户数据库表数据和索引,是所有表公用的。当打开innodb_file_per_table选项的时,.idb文件就是一个表独有的表空间,文件存储了当前表的数据和相关的索引数据。

      如何存储记录

      和大多数存储引擎一样,Inno DB的使用页作为磁盘管理的最小单位。数据在Inno DB存储引擎中都是按照行存储的,每个16KB大小的页可以存储2-200行的记录。

     数据页结构

         页(page)是InnoDB存储引擎管理数据最小磁盘单位,而B-Tree节点就是实际存放表中数据的页,我们将介绍页是如何组织和存储记录的。首先Inno DB页有以下七个部分:

mysql innodb文件有哪些 mysql innodb存储的文件结构_数据


      在页的头部和尾部之间就是就是用户记录和空闲空间了,每一个数据页都包含了Infimun和Supremum这两个虚拟的记录(可以理解为占位符) 。Infimum记录是比任何记录主键值都小的值,Supernum是该页中的最大记录。User Records就是整个页中真正用于存放记录的部分,而Free Space就是空余空间了。他是一个链表的数据结构,为了保证插入和删除的效率,整个页不会按照主键顺序对所有记录进行排序,它会从左侧到右侧寻找空白节点进行插入,行记录在物理存储上并不是按照顺序的,它们之间的顺序是通过next_record这一指针控制的。

     B+树在查找对应的记录时候,并不会查找到对应的行记录。只能定位到行所在的页,将整个页加载到内存中,在通过page Directory中的稀疏索引和next_record找出对应的行记录,不过这次操作都是在内存中进行的,索引通常会忽略这部分查找的耗时。

    

 索引的数据结构:

       InnoDB存储引擎在绝大多数情况使用B+树建立索引,这是在关系型数据库中最常见和有效的索引。但是B+树并不能直接找到一条给定键值对应的记录,只能找到对应的数据对应的页。正如上面提到的数据库把页的数据加载到内存中,然后寻找对应的数据行。

      B+树是平衡树,它会查找任意节点所耗费的时间是一样的,比较的次数就是B+树的高度。

 聚集索引和辅助索引

       数据库中的B+树索引可以分为聚集索引和辅助索引。他们之间最大的区别就是,聚集索引存放着一条行记录的全部信息,而辅助索引只包含了索引列和一个用于查找对应行记录的书签。

聚集索引:

       InnoDB引擎中的表都是使用索引组织的,也就是按照键的顺序存放。聚集索引就是按照表中主键的顺序构建一颗B+树,并在树的叶子节点中存放表中的行记录数据。聚集索引与表的物理存储方式有着非常密切的关系,所有的正常表都有且仅有一个聚集索引。表中的所有行记录都是按照聚集索引的顺序存放的。当我们使用聚集索引查找表中的数据时候,可以直接获取聚集索引所对应的整行记录所在的页,不需要进行二次操作。

辅助索引/非聚集索引:

      辅助索引也是通过B+树实现的,但是他的叶子节点并不包含行记录的全部数据,仅包含索引建和一个便于查找对应记录的书签,在InnoDB中就是当前记录的主键。辅助索引并不影响聚集索引,因为聚集索引构成的B+树是数据实际存储的形式。而辅助索引只是用于加速数据的查找,通常一张表会有多个辅助索引来提升数据的查找效率。

      通过使用辅助索引查找记录的过程: 先通过辅助索引查找到对应记录的主键id,然后在聚集索引中使用主键来获取对应的行记录,这也是通常情况下记录的查找方式。(次过程可以理解为回表)。