关于索引的定义
索引是帮助MySQL高效获取数据的
排好序
的数据结构
1. 假设我们就是MySQL的开发者
2. 打开我们某个数据库的表 和 一个查询语句
SELECT name, hobby FROM student_info WHERE age = 18
3. 看着有着巨大数据量的数据库表 和 超长的查询时间 是时候做出改变了 !
第一步合适的数据结构
不就是查询嘛?靠着我微薄的算法功底给出了第一版的解决方案
搜索二叉树
我们将数据表中的 age 作为key 整体的数据作为value 做一个二叉树,当我们需要查询数据时我们就按照左侧小右侧大的思路去查询。(凭借着log(n) 的时间复杂度 我一定能获得隔壁小美的青睐 (手动狗头))
正在我充满幻想时 隔壁的大佬给了我一个图片
啊 蛇!! 不对这是我的二叉树 咋变成这样??
(给大家安利一个特别好的数据结构网站 带你看看好康的)
分析一下他的插入顺序 1,2,3....
确实 二叉树确实会存在这种极限情况 而且在使用的时候大多也是不平衡的。。
平衡~ 平衡? 平衡!!
红黑树
对啊 依稀记起大学上数据结构课程时 依稀听到的名称 平衡二叉树
红黑树
CSDN 启动!!
文章很好, 我在左右旋转之间 CTRL + C, CTRL+V
隔壁大佬一脸鄙夷的看着我磨光的cv键 甩给我一个表
我滴妈好多数据 emm...
确实,在程序运行一年半载有这么多的数据量是很正常的事情,但这也意味着我们不可能将整个二叉树给读到磁盘中了。
B树
不能全部那就读取一部分呗!然后根据这一步分的结果来选择下一次读取那个部分
1. 我们可以先把黑色的部分读到磁盘 根据我们要求的判断结果 选择 不同的分支去读取红色对应的数据页(MySQL 的存储结构 是啥我也不太清楚)
2. 为啥非得是红黑树?? 都在磁盘了 还是有序的, emm...
我直接一手二分阁下如何应对 正好有个叫B树的数据结构深得我心(我没有开挂)
HASH
当然我们不妨吧问题想的极限一点,(只送大脑(咆哮~))
Hash 我们将数据进行一次Hash运算 让Hash后的结果集可以在磁盘中读取, 然后每一个hash值对应的一块地址 这样不是更高效吗?
B+树
SELECT name, hobby FROM student_info WHERE age >= 18
emm... 这是啥?? 准没好事 溜了溜了...
范围查询是我们必须要面对的问题,而Hash 后的结果让我们我们无法进行这种范围查询而这种查询在使用时又非常常见....
hash处理只能应对一些 相等的SQL( = ,in )这显然是不行的无奈我又回到亲爱的B 树这边(我好像是个渣男)
1. 我们在处理B树时让子节点相互之间联系起来我先拿到边界值然后沿着这个链表走不就可以了。。。
2. B树中我们在非叶子节点也会存储一些数据这样感觉有点浪费,过早的拿到数据表面上是好事,但却影响了这块区域的功能,原本一曾可以区分1000 个 子叶节点 现在只能 500 间接的增加了树的深度 我们每次取一个 块到内存走的可是IO 这玩意多了可是要挨骂的... 还是只在叶子节点存储相应的数据吧。
存储引擎
叶子节点存储啥比较好嘞 emm 全部数据还是地址嘞。。。
(关于存储引擎, 是表级别还是库级别嘞?? emm )
(我没有开挂)
引出一个小的概念
聚集索引 : 索引文件和数据文件是分离的
非聚集索引:!聚集索引(手动狗头)
其中
MyISAM索引文件和数据文件是分离的(非聚集)
而 InnoDB
孩子用的MySQL8 创建了一个表其中 这里面 既有索引又有数据,那? 表结构去哪里 我的frm 去哪里了?在MySQL8 中被存储在数据字典中了(万能的CSDN)....
那我们就得到了 InnoDB索引格式
注意哈 : 这里的数据我们指的是主键索引 至于其他的索引(二级索引) 就别存数据了(维护起来直接要老命, 而且空间 就是钱)至于叶子节点存储一个主键Id值凑合着过吧...
注意点
我们在使用B树作为存储结构是不可避免的也得到了他的部分不足
1. 主键递增
当我们进行随机数据插入时,恰好这个数据页满了... 那就遭老罪了,会产生页分裂,并维需要大量的时间去维护对应的指针 (有兴趣的自己CSDN 一下) 这边建议主键值递增处理,即便数据满了也不会影响左侧的树结构(死道友不死贫道)
2. 主键的类型
我们不可避免的需要用主键进行各种比较,同时我们的非叶子节点也是只存储了这个类型,方便比较,占空间又小 啊 Number 一个冉冉升起的选项~~ (根据具体的业务类型我们可以选择int 或者 long).
二级索引
在我们使用时很多情况并不是使用主键索引进行数据过滤,自定义的二级索引才是我们的优选项,不过对于二级索引它有啥特殊点吗?
1. 叶子节点存储的是主键值 - 我们的查询可能找不到全部的数据无奈回表(回表,回表,就是拿着Id回聚集索引去找数据呗),当然我们查询的结果往往不止一条,大量数据回表有时甚至不如全表扫描 emm....
2. 二级索引也是有序的,那拿什么作为比较条件嘞 ??
选取的字段呗, 从左往后比较,左边的相同了在比较右边的的呗(最左前缀,索引必须要保证其有序性,这种排序结构在我们前面数据为确定值时右侧的数据依旧是有序的,依然可以使用..)
菜鸟现在准备好好的学习一下MySQL的东西了,如果写的有啥问题或者建议非常感谢反馈.