mysql-索引篇2-索引的底层实现

一、常用的索引底层结构有哪些?

==索引是一种排序的,便于查找的数据结构。==

下面是一些常见数据结构的概念,具体每种类型的详细特点,再去看别的文档吧。

1. 二叉查找树:

​ 左子树的键值小于根的键值,右子树的键值大于根的键值。

2. AVL 树:

​ 平衡二叉树(AVL 树)在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为 1。

3. 红黑树:

​ 每个节点都带有颜色属性的二叉查找树。

4. 平衡多路查找树(M阶的 B树):

为磁盘等外存储设备设计的一种平衡查找树。

  • 每个节点最多有m-1个关键字(可以存有的键值对)。
  • 根节点最少可以只有1个关键字
  • 非根节点至少有m/2个关键字
  • 每个节点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。
  • 所有叶子节点都位于同一层,或者说根节点到每个叶子节点的长度都相同。
  • ==每个节点都存有索引和数据,也就是对应的key和value。==
  • ==数据库中的节点 value 其实是指针。。==

5. B+树:

B+树其实和B树是非常相似的,我们首先看看相同点

  • 根节点至少一个元素
  • 非根节点元素范围:m/2 <= k <= m-1

不同点

  • B+树有两种类型的节点:==内部节点不存储数据,只存储索引,数据都存储在叶子节点。==
  • 内部结点中的key都按照从小到大的顺序排列,对于内部结点中的一个key,左树中的所有key都小于它,右子树中的key都大于等于它。叶子结点中的记录也按照key的大小排列
  • 每个叶子结点都存有相邻叶子结点的指针,叶子结点本身依关键字的大小自小而大顺序链接。
  • 父节点存有右孩子的第一个元素的索引

img

二、Mysql 的两种存储引擎的索引

文档主要介绍 MyISAM 和 InnoDB 两个存储引擎的索引实现方式。 两者均使用的B+ 树实现的索引。

2.1 InnoDB索引实现

1)主键索引(聚簇索引,B+树):

主键默认采用聚簇索引(聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法。特点是存储数据的顺序和索引顺序一致),且一张表只允许存在一个聚簇索引。

​ ==聚簇索引的叶子节点就是数据节点(存放完整的行数据)==

​ ==非聚簇索引的叶子节点保存非完整行的数据(只有对应的键值数据) + 书签(主键的聚集索引的索引值)==

​ 叶子节点是数据页(默认16K)。==每个数据页上存放的是完整的行记录。B+ 树将 叶子页加载到内存后,再去查找对应数据行。==

​ 非叶子节点、存放的仅仅是键值及指向数据页的偏移量

聚集索引的好处:

  • 对于主键的排序查找非常的快(因为其叶子节点是用双向链表链接的)
  • 对于主键的范围查找非常的快(因为通过叶子节点的上层中间节点,就可以得到叶结点的范围值)

    在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,**这棵树的叶节点data域保存了完整的数据记录。索引的key是数据表的主键(primary key),因此InnoDB表数据文件本身就是主索引。

img

InnoDB存储引擎的最小存储单元是页(16K),页可以用于存放数据也可以用于存放键值+指针, 在InnoDB中B+树高度一般为1-3层它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次IO操作即可查找到数据

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

2)InnoDB的辅助索引(非聚簇索引,B+树/ B树)

B+树:

非聚簇索引的叶子节点保存非完整行的数据(只有对应的键值数据) + 书签(主键的聚集索引的索引值)

二级索引使用非聚簇索引。

通过二级索引查询首先,查到是主键值和对应的数据字段,如果查询的字段更多,InnoDB再根据查到的主键值通过主键索引找到相应的数据块。( 这个流程叫 回表

B树:覆盖索引用到的。

InnoDB 表是基于聚簇索引建立的。因此InnoDB 的索引能提供一种非常快速的主键查找性能。它的辅助索引(Secondary Index, 也就是非主键索引)也会包含主键列,所以,如果主键定义的比较大,其他索引也将很大。如果想在表上定义 、很多索引,则争取尽量把主键定义得小一些。InnoDB 不会压缩索引。

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

img

1、为什么不建议使用过长的字段作为主键?

因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。

2、用非单调的字段作为主键在InnoDB中不是个好主意?

因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效。

2.2 MyISAM索引实现:MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。

MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。

1)主键索引(非聚簇索引,B+树):

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。下图是MyISAM主键索引的原理图:

img

2)辅助索引(Secondary key)

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

同样也是一颗B+Tree,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

MyISAM的索引方式也叫做“非聚簇”的,之所以这么称呼是为了与InnoDB的聚簇索引区分。

三、为什么说B+树比B树更适合数据库索引?

1、 B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。(B 树 非叶子节点中还包含了数据指针,所以占空间大)

2、B+树的查询效率更加稳定(数据都存在叶子节点,路径都是从根到叶子的路径,一般3次以下的IO读取,等于树的高度)

B树不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少),指针少的情况下要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低;

3、由于B+树的数据都存储在叶子结点中,非叶子点均为索引,**方便全盘扫描和范围查找。**

但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值