索引
是一种已经排好序的数据结构,常用的类型有以下几种
- 二叉树
- 红黑树
- Hash表
- B树
- B+树
数据结构图形化界面:Data Structure Visualization
二叉树
又称为二叉查找树,是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,且当前节点大于左子树并小于右子树,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点。
值不断增大插入的时候,新插入的值会作为右子树,此时的二叉树就像一个单向链表
数据插入时,会不断的和每一个节点进行比较,若小于则放在当前节点的左子树,大于则放在右子树
mysql未将它作为索引的数据结构,原因是查询的效率太慢了;若一张表中的数据量太大可能就需要遍历整个二叉树来进行查找,而索引文件是存在磁盘中的,查询次数过多的IO操作及其耗费时间。
AVL树(平衡二叉树)
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
举例按顺序插入 1,2,4 ,构造出来的结果会如下所示
插入1,2
插入4
相比较二叉查找树,平衡二叉树会在插入元素后检查左右子树的高度差,若超过1,则会进行平衡,按照二叉树的特性进行旋转
红黑树
红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组,红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树,但对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。
特点
- 结点是红色或黑色。
- 根结点是黑色。
- 所有叶子都是黑色。(叶子是NIL结点)
- 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
- 从任一节结点到其每个叶子的所有路径都包含相同数目的黑色结点
和AVL树一样,红黑树也会保持平衡
B树
相比较二叉树和红黑树,一个节点只能存放一个元素,B树的每一个节点是可以存放多个索引+数据的,就像一个元素和一个数组的区别
特点
- 叶节点具有相同的深度,叶节点的指针为空
- 所有索引元素不重复
- 节点中的数据索引从左到右递增排列
在mysql的设定中,一个节点可存储的数据量为16kb,但B数的节点不仅仅存储索引,还存储了该索引对应的数据行的数据,因此,在使用B树的时候,每一个节点可以存放的索引数量不会很多;在表数据量越大的情况下,B树的高度会越高,故在查询的时候会越慢
B+树
特点
- 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间访问的性能
在mysql中的数据结构
和B树的区别在于,非叶子节点没有数据,只存储索引(存在冗余),在相同的存储容量的条件下,每个非叶子节点可存储的索引数量=16K/索引大小(占用的空间很小,以16B为例),每增加一个高度,可存储的数据量就变为原来的1024(16K/16B)倍;并且在B+数中的叶子节点中存储着指向上、下叶子节点的指针,用来加快查询速率。
Hash表
特点
- 对索引的key进行一次hash计算就可以定位出数据存储的位置
- 很多时候Hash索引要比B+ 树索引更高效
- 仅能满足 “=”,“IN”,不支持范围查询
- hash冲突问题
存储引擎
存储引擎就是指表的类型以及表持久化存在磁盘的存储方式,它是针对表的一种处理方式,当然,数据库也有存储引擎,但一般都是指的表的存储,一般情况下mysql默认的存储引擎是innodb。
MyISAM存储引擎索引实现
使用MyISAM使用时,其索引文件和数据文件是独立分离的,其特点是存储快查询慢,故现在大部分对查询要求比较高的业务场景都是使用innoDB的存储引擎。
InnoDB存储引擎索引实现
- 表数据文件本身就是按B+Tree组织的一个索引结构文件
- 聚集索引-叶节点包含了完整的数据记录
建议InnoDB表必须建主键的理由:主键的特点就是主键的值不可重复,也不可为空,正好符合B+树key的要求,而如果表中没有主键,会选择一个唯一的非空索引来代替主键构建B+树;若表中连索引都没有,则会使用一个隐式的定义一个不可见的列来作为主键,用以构建B+树。
并且推荐使用整型的自增主键原因:使用整型的原因在于,B+树是有序存储的,在构建索引的时候,整型的排序对比显然要比字符类型的逐位比较快的多;而使用自增的原因在于,在索引插入的时候,自增的主键会直接在尾部插入,若是非自增的,插入的时候就要遍历查找该新增项的数值位于B+树的哪一个节点,相比直接的尾部插入要更耗费资源。
假设现在有一张InnoDB的表,存储了id、age、name等列,且id作为主键。
主键索引
非主键索引
非主键索引结构叶子节点存储的是主键值原因:对于innoDB的表来说,只有一个以唯一主键作为聚集索引的B+树,而非主键索引存储的数据则是,以主键作为索引的B+树的索引列,这样更能节省存储空间,也能保持数据一致性。
索引最左前缀原则
联合索引存储结构
由多个字段组合成的一个索引称之为联合索引,其底层也是一个B+数,相比于单列索引,联合索引会按照索引建立的顺序来对表中的数据进行排序,比如建立索引时是(id,age,name),那么在排序的时候就会先比较id然后比较age,最后比较name,就类似mysql中的order by排序,会根据后面的列依次进行。
为何联合索引使用时会要最左匹配,原因在于索引的数据结构就是一种已经排好了顺序的数据集合;若不按索引建立的顺序来使用,查询时就无法通过索引来快速的定位到需要的数据