InnoDB 一棵 B+ 树的存放数据量的计算
底层存储按页:数据量=指针页指针数*数据页的数量*数据页存储的数据量
对于叶子结点一页大小树16k,如果一行数据数据大小是1k,则每页可存储16k/1k=16行数据;
对于非叶子结点,存储的是主键值和指针(主键值越大需要空间越大则能存储的数据就越少),假设主键是bigint 8字节,指针一般设置为6字节,则一条是8+6=14字节,一页16k/14字节=16384/14=1170条数据;
则对于高度是2的B+树,存储的数据量是:16*1170=18720行数据;
对于高度是3的B+树,存储的数据量是:1170*1170*16=21902400行数据;
所以一般一个mysql表的B+树高度在1-3层即可满足,一层高度即一次IO,平均1-3次IO即可查到数据。假如计算机的性能是1s进行100次IO,则1次IO是0.01秒,那么每次数据的查询是0.01-0.03s;
B+树和B-树(即B树)的区别:
B+树:数据只存储在叶子结点;叶子节点间用指针串起来;
B-树(即B树):所有节点存储关键字和数据;叶子节点无关联;
具体:1、B+树的非叶子节点存储的只有主键+指针,数据小,一页能存储的数据量大;而B-树的非叶子结点还会保存具体的数据,数据大,导致一页存储的数据量小,即达不到1170个指针数,那么必然导致树的高度增高,IO次数变多;2、B+树所有的Data域在叶子节点,所有的叶子节点用指针串起来两两链接,形成的双向环形链表,顺序查询性能比较高。这样遍历叶子节点就能获得全部数据,就能进行区间访问且实现整棵树的遍历,而且在数据库中基于范围的查询是非常频繁的,而B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题,B树不支持这样的操作(或者说效率太低)。
最左匹配原则:
会有最左原则,是因为联合索引的B+Tree是按照第一个关键字进行索引排列的。
B+树和红黑树:
红黑树的树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况
MongoDB用B-树,从它的设计角度来考虑,它并不是传统的关系性数据库,而是以Json格式作为存储的nosql,目的就是高性能,高可用,易扩展。首先它摆脱了关系模型,其次Mysql由于使用B+树,数据都在叶节点上,每次查询都需要访问到叶节点,而MongoDB使用B-树,所有节点都有Data域,只要找到指定索引就可以进行访问,无疑单次查询平均快于Mysql(但侧面来看Mysql至少平均查询耗时差不多)。总体来说,Mysql选用B+树和MongoDB选用B-树还是以自己的需求来选择的。