文章目录
索引
索引是什么
官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。
聚簇&非聚簇索引
聚簇索引(主索引)
聚簇索引也叫聚集索引或者主索引,它并不是一种单独的索引类型,而是一种数据存储方式。在聚簇索引中,数据行的物理存储顺序与索引顺序相同,即数据是按照索引键的顺序存储的。聚簇索引的叶子节点保存了一行记录的所有列信息,也就是说,叶子节点中包含了一个完整的记录行。
聚簇索引的自动创建
在MySQL中,如果使用InnoDB存储引擎,当表定义主键时,InnoDB会自动为该主键创建聚簇索引。这是因为InnoDB表总是按照主键进行排序存储的,这种索引就是聚簇索引。
聚簇索引的特点是存储数据的顺序和索引顺序一致,且一个表只能有一个聚簇索引。在InnoDB中,如果没有显式定义主键,但表中存在唯一非空索引,则InnoDB会将其选作聚簇索引。如果连这样的唯一非空索引也不存在,InnoDB会自动生成一个隐藏的、包含6字节长度的聚簇索引,用于优化某些操作。
特点
聚簇索引是将数据放在了叶子节点,找到索引也就是找到了数据。由于是按照创造索引的字段进行排序,所以进行范围查询时非常的高效。但是每一个表只能有一个聚簇索引,如果频繁的插入或者删除数据,可能导致数据页的频繁分裂和合并。
非聚簇索引(辅助索引)
非聚簇索引也叫辅助索引、普通索引。非聚簇索引的叶子节点只包含聚簇索引的键(或指向聚簇索引的指针),而不包含完整的记录行。因此,通过非聚簇索引查找记录时,需要先找到主键,然后再通过主键到聚簇索引中找到对应的记录行,这个过程被称为回表。
特点
非聚簇索引可以有多个
非聚簇索引是分开存储的,所以适合更新或者插入数据的场景。因为更新时候只需要更新索引而不需要移动数据。
范围查询的效率较低,需要回表查询,所以效率较低
索引的实现方式
Hash
Hash
是一种基于Hash函数实现的数据结构,底层原理包括了以下三个方面:
- 哈希函数(Hash Function): 哈希函数是哈希表的核心,它接受一个键作为输入,并输出该键对应的哈希值。哈希函数应该具有以下特性:
- 对于相同的键,哈希函数应该始终返回相同的哈希值。
- 哈希函数应该尽可能均匀地将不同的键映射到不同的哈希值,以减少哈希冲突的发生。
- 哈希函数的计算速度应该尽可能快,以保证高效的插入和查找操作。
- 哈希表数组(Array): 哈希表通常由一个数组来存储数据。数组的每个元素称为一个桶(Bucket),每个桶可以存储一个或多个键值对。哈希表的长度通常是固定的,但也可以根据需要进行动态扩容。
- 解决哈希冲突: 由于不同的键可能映射到数组中的同一个位置,可能会发生哈希冲突。常见的解决哈希冲突的方法包括:
- 链地址法(Separate Chaining):在哈希表的每个桶中维护一个链表或者其他数据结构(如红黑树),用于存储发生哈希冲突的键值对。
- 开放地址法(Open Addressing):在发生哈希冲突时,线性地探查哈希表的其他位置,直到找到一个空闲的位置来存储键值对。常见的探查方法包括线性探查、二次探查、双重哈希等。
- 哈希表的装载因子(Load Factor): 哈希表的装载因子是指哈希表中已存储的键值对数目与哈希表长度之比。装载因子的大小会影响哈希表的性能,通常会根据装载因子的阈值进行动态扩容或者收缩,以保持哈希表的性能。
BTree(多路平衡二叉树)
普通的二叉树,根节点如果选的不好的话最后的树会达不到加速查询的效果,普通二叉树的进化平衡二叉树在我们使用的时候已经好了很多了,但是他如果节点变得很多,那么遍历的路径也会很长,查询的效果也会变差,并且还不能支持范围查找。所以我们需要多路平衡二叉树来解决我们这个问题。
B 树
每一个节点都是由 : 键值 + data + 子节点的指针构成
- 键值:设置索引的值
- data:保存了当前记录中除了索引项外的其他数据
- 子节点指针:指向了叶子节点
**优点:**查询的时候只需要比较索引的值就可以快速的找出目标值,不用把全部的信息读入内存中进行比较。
**缺点:**不支持范围查询,需要将范围内的每一个从根节点挨个查询
B+树(Mysql现在使用树结构)
B+树的非叶子节点都只是存储查找的键值,不存储数据,而叶子节点存储了全部的索引项数据,每一次查询都是需要查询到叶子节点。
叶子节点:可能不是一个单个的值,会是一块数据,里面有好几个data
或者指向data
的指针(InnoDB中Data存储的为行数据,而MyIsam中存储的是磁盘地址)。叶子节点都是使用指针连接起来的
**优点:**可以进行范围查询,只需要找到起始节点就可以。磁盘读写很快,因为非叶子节点只存储关键信息,不存储data;
**缺点:**更新操作复杂,空间占用会相较于B树多一点。
两种实现方式区别
索引的实现其实主流有两种方式:
- 一种是
Hash
方式,但是这种的根据key - value的存储方式,很适合直接的等值查找,不适合经常使用范围查找。 - 一种是Btree,这种实现方式在等值查询的时候速度没有hash快,但是在进行范围查询的时候是不用遍历全表的,支持范围查询。
引申
红黑树
也是一种自平衡二叉树,它具有以下特性:
红黑树具有以下特性:
- 节点颜色: 每个节点要么是红色,要么是黑色。
- 根节点: 根节点是黑色的。
- 叶子