**
MySQL索引底层的数据结构与算法
**
什么是索引
大家平时老说索引,现在解释一下什么是索引?能回答的上来么?大学老师给的理解方式是,就是将索引理解为书本的目录,通过目录查找内容更快,的确这样却比喻没有什么不对,但是还是没有说清楚什么是索引。
官方给出的解释是,索引就是排好序的数据结构。
这里有2个关键点,排好序,数据结构。
先说数据结构,
mysql的存储引擎采用那种数据结构?
首先mysql的存储引擎有哪些?大家都知道innodb,和MyIsam,
这2个存储引擎有什么区别呢?
innodb的存储引擎,假如使用b+tree的数据结构,那么在叶子节点存储的就是这条数据(假如有主键索引),如果没有主键索引,mysql会默认给每行数据尾部添加rowid列,当做索引列,那们最后也会找到对应的数据,但是会耗费mysql的性能。
myisam引擎,在叶子节点,存储的数据是当前数据对应磁盘的地址,然后再根据这个地址去i/o数据,所以从这点上,还是选择innodb作为存储引擎更为合适。
再说说数据结构,为啥不用二叉树,红黑树,hash,来作为索引的数据结构。
二叉树,假如使用二叉树作为索引结构,每顺序插入数据进入数据库,由于二叉树的特性,需要与现存的数据结构做对比,然后再放到最右侧树,这样存储过程,对比次数越来越多,然后层级也越来越高,查找数据很慢。
红黑树,类似于二叉树,只不过红黑树的层级稍微好点,在插入数据的时候,会去平衡左右子树,但是一个节点就1个数据,数据量大情况下,存储和查询都是很慢。
hash,使用hash来存储数据,其实hash本身很快,但是使用hash作为索引的存储结构后,会存在问题,hash采用的md5算法,经过hash算出来的索引,只能使用等值,或者in这样的查询语句,对于范围的查询,就无济于事了。另外hash肯定会出现碰撞,存储碰撞的数据,还是需要逐一比对。所以从功能上将hash刨除出去了。
那为啥采用B+TREE,作为索引的存储结构。首先,数据库采用b+tree,那么树的层级最多就3,4层,b+tree的一个节点,俗称一页数据,为16k的数据,一个值的索引值大约占据14byte,161024/14约等于1170,就是说一个节点可以存储1170个索引值,那3层数据就是,11701170*1170=16亿条数据的索引,所以采用b+TREE,数据结构来存储索引数据,效率高,并且够用了。那为啥快。
再说排好序。
使用B+tree的结构,每一层索引值是有顺序,这个就好比在查询时候,从根节点使用一次2分查找,就知道下一层的节点位置,以此类推,很快就能确定数据的位置。然后,每个叶子节点之间也有前后的顺序,进行范围查询时,只要根据起始和终点的索引,就能很快定位出来范围。返回回去。