ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL学习总结 - 常见的索引模型

2022-05-07 16:00:10  阅读:199  来源: 互联网

标签:hash 模型 查询 索引 二叉树 key MySQL ID card


目录

MySQL学习总结 - 常见的索引模型

索引一句话简单说,就是为了提高数据查询的速度,类似于书的目录,例如文章上面开头的目录结构。

hash表

哈希表是一种key-value的结构,通过hash函数将给出的key计算出value值需要存放的位置,再将value值放入数组对应位置中。当然不可避免,不同的key通过hash函数会得到相同的值,出现hash冲突。一种做法是直接采用拉链法更多见附录,即hash函数的结果相同value,通过链表串联起来,保存在数组的对应位置。

例如,以通过id_card作为key值存储到hash表中。如下图所示,key: ID_card_n1通过hash函数计算出下标为M,所以将其对应的User1存储到数组下标为M中。而ID_card_n2和ID_card_n3计算出来的结果都是N,所以将User2和User4通过链表链接起来,保存在数组下标N的位置中。而链表中的做法是直接追加到尾部,没有进行排序。

image-20220507142308384

当需要通过key值查询时,直接通过hash值计算下标即可。如果存在hash冲突,再遍历链表,挨个比较key值进行匹配。例如通过ID_card_n2搜索时,首先计算下标为N,发现存在hash冲突,这遍历链表比较key值,匹配到User2。

优点:
能够通过主键快速定位,能够通过hash值快速定位记录位置。当出现hash冲突时,通过拉链法解决。在等值查询时很优秀。

缺点:
在范围查询时很麻烦,例如要查询id在[1, 1000]内的所有数据,需要遍历hash范围内的所有值,挨个去查询,效率很低

所以哈希表在等值查询中表现很优秀,适用于Memcached等一些NoSQL使用

有序数组

有序数组通过Key进行升/降序排序。保证主键唯一的前提下,当等值查询时,直接通过二分查找法,即可快速定位,时间复杂度为\(O(log(N))\)。范围查询时,可先通过二分法找到左边界所在位置,再向右遍历比较右边界即可。

依旧以上面的案例为例子,有序数组对应的图如下:

image-20220507145213427

当要找到key值为ID_card_n4时,直接二分查找即可定位。当要找出[ID_card_n4, ID_card_n2]之间所有元素时,首先通过二分法找到ID_card_n4所在位置,再向右遍历,挨个比较key是否为ID_card_n2,找到即停止遍历,也可以快速找到所有的元素。

单看查询效率来说,有序数据的效率无疑很高,但是当存在数据量变动就效率很低了。如果要在中间插入或者删除元素,无疑是致命的。删除可以通过加入标志位进行规避,但是在插入时,还是需要将后面的元素向后挪动一位,这效率太低了。

优点:
对于等值查询,通过二分法可快速定位位置,时间复杂度为o(log(N))
对于范围查询,通过二分法来查询到左边界条件后,向右边界条件直接遍历获取即可

缺点:
当有数据插入数组中间时很繁琐,需要挪动数据,再能进行插入操作。

所以有序数组对于静态数据存储很友好,例如2021年安徽省各市的天气信息。这种数据不会存在修改的场景。

二叉搜索树/平衡二叉树

上面的场景,通过二叉搜索树即可得到下面的图。二叉搜索树的特点:左孩子<父节点<右孩子

image-20220507150248482

如图要找ID_card_n2时,路径如下: UserA -> UserC -> UserF -> User2,此时时间复杂度为\(O(log(N))\)。

二叉搜索树存在一个问题,数据恰好是有序的,这二叉树会退化为一个链表,导致查询时时间复杂度升为\(O(N)\)。二叉搜索树最好的情况就是恰好是一颗平衡二叉树,此时的时间复杂度即为\(O(log(N))\)。当然平衡二叉树更新时需要维护树的结构,更新的时间复杂度也为\(O(log(N))\)。

但是二叉搜索树&平衡二叉树在存储引擎中并不常用,因为索引还需要落到磁盘中。如果有100W条数据需要建立索引,那么对于100W个节点的平衡二叉树,树的高度就有20层。意味着需要从磁盘至少读取20次数据块,假设我们读取一次硬盘的速度为10ms,\(20 * 10 = 200\)ms,这个查询效率无疑并不高效。所以更多的采用N叉树来压缩树的高度,以减少读取磁盘的次数,提升查询效率。

标签:hash,模型,查询,索引,二叉树,key,MySQL,ID,card
来源: https://www.cnblogs.com/toughtful/p/16242865.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有