1. mysql存储数据的基本单元是名为page的数据结构,缺省状态每个page允许16kb的空间
2. page就是一个增强的hashmap,它包括这一页内部数据的key和value,key就是我们建表时的主键,value就是那一行真实数据。除此以外,page还包括指向前一个和后一个page的指针,包括一个自己这个page从哪个真实数据的主键开始的记录
3. 因为一个page只有16kb对吧,随着数据越来越多,那page也越来越多对吧,即使page告诉你它从哪个索引开始,你查也要遍历,不就慢了吗,所以我们需要一个page来管理这些page,就像hashmap一样用key直达。当你把第一个管理page的page放进来的时候,这就是第一层b+树,当数据更多的时候,管理page的page也越来越多,那就需要第三层page来进一步管理,这就是两层b+树,以此类推,最终形成一个层层嵌套的hashmap结构,这就是b+树咯
4. 那为什么page需要前后指针做成双链表呢?因为主键,比如就是id吧,查id大于10或者小于10的数据,那是不是就不需要一次次走树结构,只需要把id为10的数据的前指针或后指针吐出来就行,就快很多
5. 那为什么mysql表推荐用自增主键呀?因为形成b+树更容易,我只需要按顺序往page后面贴数据就行,不需要做页内搬运计算
6. 好了,单主键我们看完了,那联合索引呢?联合索引就是按照你指定的ABC三个字段,形成先排序A再排序B再排序C的有先后的主键,等于在b+树中用A做key找B,用B做key找C,所以如果查询的时候跳过了A,所有的索引就不生效了,因为你没有key,就没法用hashmap。有A没有B,那A会生效B不生效,原理一样
7. 那么varchar字段为什么我加了索引,在做like ‘%bc%’的时候也会索引失效呀?和6一样,varchar按照字典序构建b+树,缺了最左的数据,没法查hashmap,就这么简单
8. 那么回表又是什么呀?简单,我们在搞主键索引的时候,不是已经把真实数据存下来了嘛,那在构建其他索引的时候还需要存真实数据吗?不需要,浪费空间,所以我们查别的索引的时候,只需要在其他索引的b+树里查叶子结点的主键,那是不是就可以去主键索引的树查了呀?这就叫回表
9. 那么覆盖索引为什么快呀?因为你要查询的字段都在b+树维护的索引树里面,跳过了8当中回表这一步,所以快
10. 那么什么是聚簇索引什么是非聚簇索引呀?用来索引page的page就是聚簇索引,意思是把索引聚起来,反之就是非聚簇咯
11. 为什么mysql不适合做全文索引而es可以呀?因为mysql用了b+树,对于字符串检索需要有从左到右的顺序,但es通过分词做了倒排索引,所以很容易做全文索引