1 Hash算法
1 定义
哈希算法:也叫散列算法,就是把任意值(key)通过哈希函数变换为固定长度的 key 地址,通过这个地址进行具体数据的数据结构。
2 查询原理
- 如果我们需要检索 id=7 的数据
- 哈希算法首先计算存储 id=7 的数据的物理地址 addr=hash(7)=4231,
- 而 4231 映射的物理地址是 0x77,0x77 就是 id=7 存储的额数据的物理地址,
- 通过该独立地址可以找到对应 user_name='g'这个数据。
- 这就是哈希算法快速检索数据的计算过程
3 哈希碰撞
就是哈希函数可能对不同的 key 会计算出同一个结果比如 hash(7)可能跟 hash(199)计算出来的结果一样,也就是不同的 key 映射到同一个结果了,这就是碰撞问题。
解决碰撞问题的一个常见处理方式就是链地址法即用链表把碰撞的数据接连起来, 计算哈希值之后,还需要检查该哈希值是否存在碰撞数据链表,有则一直遍历到链表尾,直达找到真正的 key 对应的数据为止。
4 弊端
范围查找时, 如果使用哈希算法实现的索引,范围查找怎么做呢?一个简单的思路就是一次把所有数据找出来加载到内存,然后再在内存里筛选筛选目标范围内的数据。但是这个范围查找的方法也太笨重了,没有一点效率而言。
5 总结
所以,使用哈希算法实现的索引虽然可以做到快速检索数据,但是没办法做数据高效范围查找,因此哈希索引是不适合作为 Mysql 的底层索引的数据结构。
2 二叉查找树(BST)
1 弊端
极端情况下会退化为线性链表,二分查找也会退化为遍历查找,时间复杂退化为 O(N),检索性能急剧下降。比如以下这个情况,二叉树已经极度不平衡了,已经退化为链表了,检索速度大大降低。此时检索 id=7 的数据的所需要计算的次数已经变为 7 了。
2 总结
在数据库中,数据的自增是一个很常见的形式,比如一个表的主键是 id,而主键一般默认都是自增的,如果采取二叉树这种数据结构作为索引,那上面介绍到的不平衡状态导致的线性查找的问题必然出现。因此,简单的二叉查找树存在不平衡导致的检索性能降低的问题,是不能直接用于实现 Mysql 底层索引的。
3 B-Tree