正在读取目录
Myisam引擎(非聚集索引)Innodb引擎(聚集索引)磁盘数据页的存储结构主键索引页存储结构
什么是索引:
索引是一种可以高效获取数据的存储结构,比如哈希、二进制、红与黑。
MySQL为什么用B+树代替上面三种数据结构:
如果只从id=45的表中选择*的话,上面三种算法都可以很容易实现,但是如果从id<>注:
b+树只在最后一个叶子节点存储数据,叶子节点以链表的形式互相指向。
b+树的性质
(1)从图中可以看出,单个节点可以存储更多的数据,从而减少磁盘IO次数。
(2)叶节点形成有序链表,便于进行范围运算。
(3)在聚集索引中,叶节点的数据直接包含数据;在非聚集索引中,叶节点存储指向数据地址的指针。
回到顶端
Myisam引擎(非聚集索引)
如果该引擎用于创建数据库表,则创建表用户(…...),它实际上生成了三个文件:
User.myi索引文件user.myd数据文件user.frm数据结构类型。
下图:当我们执行select * from user where id = 1时,它的执行过程。
(1)检查表格的myi文件是否有按id索引的索引树。
(2)根据这个id索引找到叶子节点的id值,从而得到其中的数据地址。(叶节点存储索引和数据地址)。
(3)根据数据地址,在myd文件中找到对应的数据并返回。
回到顶端
Innodb引擎(聚集索引)
如果该引擎用于创建数据库表,则创建表用户(…...),它实际上会生成两个文件:
User.ibd表索引和数据文件user.frm表结构类型
因为默认情况下innodb engine创建的表是由主键索引的,所以不需要myi文件。
下面是innodb表的结构图:很明显,它和myisam最大的区别是,整个数据都存储在叶子节点,而不是地址。(叶节点存储主键索引和数据信息)
此时,如果在其他列中创建索引,如name,它将创建另一个以name为索引的索引树(叶子节点存储索引和主键索引)。
您正在执行SELECT * FROM USER,其中NAME =' Leo '。他的执行过程如下:
(1)找到名称索引树
(2)根据name的值找到树下叶子的名称索引和主键值。
(3)使用主键值删除索引树的主键值和叶节点的数据信息。
MyISAM引擎与InnoDB引擎的区别[/brMyISAM:支持全文索引;不支持交易记录;是手表级别的锁;将保存表中的具体行数。
InnoDB:全文索引要到5.6版才可用;支持服务;它是一把星锁;不会保存表中的具体行数。
通用:无事务时,适用于计数计算量大的myisam引擎。高可靠性要求是使用innodby发动机。推荐InnoDB引擎。
添加索引后,查询速度可以大大提高,但索引越多越好。一方面会占用存储空间空,另一方面会使写操作变慢。通常,我们用频繁查询和更多的值来索引列。
例如:select * from user where *** = “女”不需要为此建立索引,因为性别只有两个值,查询本身也比较快。
select * from user where user_id = 1995,这个需要索引,因为user _ id的值很多。
回到顶端
磁盘页面的存储结构
磁盘中的数据页是按顺序逐页存储的,然后两个相邻的数据页会以双向链表的格式互相引用。每一行数据都会按照主键的大小进行排序存储,每一行数据都有一个指向下一行数据位置的指针,形成一个单向链表。起初,第一行是起始行,它的行类型是2,这是最小的行。然后,他有一个指向下一行数据的指针,每一行都有自己的每个字段的值。然后,每一行都通过指针不断指向下一行数据。普通数据行都是0类型,最后一行是3类型,代表最大的一行。
正如我们刚才所说,数据页中的数据行必须按照主键的大小按正序排列。下一页的主键也将大于上一页的主键。自增则自生,自生则乱。Mysql会通过
分页
的机制将数据移动到上一个数据页,保证下一个数据页中的主键值大于上一个数据页中的主键值。
回到顶端
主键索引页存储结构
只要每个数据页及其最小主键值都包含在主键索引中,主键索引的目录结构就可以形成索引目录。然后,在您查询主键值之后,您可以通过目录中的二分搜索法直接定位该数据所属的数据页,然后您可以通过数据页中的二分搜索法定位该数据。
现在问题来了。您的表中可能有很多数据。例如,一个表中可能有几百万、几千万甚至几亿个数据。所以这个时候你可能有大量的数据页,然后你的主键目录会存储大量的数据页和最小主键值。如何做到这一点?所以在考虑这个问题时,实际上是通过将索引数据存储在数据页中来完成的。也就是我们上面说的b+树结构。
比如我现在要找id=45的数据,我会先从35页中找到23页,然后找到6页,最后找到第4页。然后指向叶节点(数据页)。
如果您基于非主键字段名称构建索引,那么当您插入数据时,您将创建一个新的B+树。B+树的叶节点也是数据页,但是这个数据页中只放了主键字段和名称字段,数据行按照名称的大小排列,不是具体的数据。先找到name对应的主键地址,再去主键索引树找到具体的数据信息。这种行为叫做
回表查询
(如果select的所有字段都是索引中的字段,就直接返回,不用在主键索引树中找。这种行为称为
覆盖索引)
本文来自MR.特别人士投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/625930.html