mysql索引插入动图: https://www.cs.usfca.edu/~galles/visualization/flash.html
1、innodb 数据索引在同一文件
mylsam 文件索引在不同文件
2、mysql为什么用b+tree数据结构做索引?
链表的时间复杂度为O(n)
红黑树为O(logn) ,mysql不用此作索引,原因是1、只有两路;2、不够平衡。3、没有解决树的深度。因为每次只能取出一行数据,所以随着树的深度增加需要进行多少IO操作,红黑树一般只放在内存里面用。例如 Java 的 TreeMap。
hash: 对name做hash,数据量大的情况下会出现hash冲突,碰撞,如果出现碰撞则会对key引入一个链表,增加了负责都,
其次也解决不了排序,范围等问题。
btree: btree存在一个度的概念,达到后会分裂。降低了树的深度。btree会在索引下面挂载数据,造成度会很小。从而增加了树的深度。
b+tree: 优化了叶子节点,根节点会出现在叶子节点,形成一个有序叶子,非叶子节点不存储数据,叶子节点挂载数据。
叶子节点之间形成的指针,更加适合顺序,范围查找,减少了io操作。
注意:
非主键索引,叶子节点存储的是主键。原因是:如果存在多个索引,叶子节点存储数据的话,则会造成数据重复和数据不一致的问题。
主键索引,叶子节点存储的是数据。
为什么不推荐主键用uuid?
1、uuid是无序的,每次插入数据会动态调整树的顺序,调整树的结构,
2、uuid占空间大32位。
innodb必须要有主键吗???
必须有,innodb会根据唯一键生成一个主键,如果没有的话innodb会生成一个虚拟主键。
红黑树:
红黑树也是 BST 树,但是不是严格平衡的。
必须满足 5 个约束:
1、节点分为红色或者黑色。
2、根节点必须是黑色的。
3、叶子节点都是黑色的 NULL 节点。
4、红色节点的两个子节点都是黑色(不允许两个相邻的红色节点)。
5、从任意节点出发,到其每个叶子节点的路径中包含相同数量的黑色节点。
多路平衡查找树(B Tree)(分裂、合并)
Balanced Tree这个就是我们的多路平衡查找树,叫做 B Tree(B 代表平衡)。
跟 AVL 树一样,B 树在枝节点和叶子节点存储键值、数据地址、节点引用。
特点:1、分叉数(路数)永远比关键字数多 1。比如我们画的这棵树,每个节点存储两个关键字,那么就会有三个指针指向三个子节点。
2、如果删除节点,会有相反的合并的操作。注意这里是分裂和合并,跟 AVL 树的左旋和右旋是不一样的
B+ Tree
特点:1、它的关键字的数量是跟路数相等的;
2、B+Tree 的根节点和枝节点中都不会存储数据,只有叶子节点才存储数据。搜索到关键字不会直接返回,会到最后一层的叶子节点。比如我们搜索 id=28,虽然在第一
层直接命中了,但是全部的数据在叶子节点上面,所以我还要继续往下搜索,一直到叶子节点
3、B+Tree 的每个叶子节点增加了一个指向相邻叶子节点的指针,它的最后一个数据会指向下一个叶子节点的第一个数据,形成了一个有序链表的结构。
4、它是根据左闭右开的区间 [ )来检索数据。
总结一下,InnoDB 中的 B+Tree 的特点:
1)它是 B Tree 的变种,B Tree 能解决的问题,它都能解决。B Tree 解决的两大问题是什么?(每个节点存储更多关键字;路数更多)
2)扫库、扫表能力更强(如果我们要对表进行全表扫描,只需要遍历叶子节点就可以了,不需要遍历整棵 B+Tree 拿到所有的数据)
3) B+Tree 的磁盘读写能力相对于 B Tree 来说更强(根节点和枝节点不保存数据区,所以一个节点可以保存更多的关键字,一次磁盘加载的关键字更多)
4)排序能力更强(因为叶子节点上有下一个数据区的指针,数据形成了链表)
5)效率更加稳定(B+Tree 永远是在叶子节点拿到数据,所以 IO 次数是稳定的)