B-Tree / B+Tree 结构以及MySQL索引
来源:互联网 发布:杨千嬅 唱功 知乎 编辑:程序博客网 时间:2024/05/21 11:12
对MySQL的索引相关的问题以前一直很不清楚,最近了解了下树和索引之间的关系,对这方面有了新的认识,感觉豁然开朗,留下一些笔记。
- B-树
B-树不一定是二叉树,B树是一种平衡树,它的高度是固定的;
B树是一种多路查找树,也就是说它的节点上有多个存储的值;
BTree每个节点存储的数据量很大,可以算一算,每个节点的数据如果为100个,层高M为3,则总的数据量,将近似为:(1000+1)^3 - 1;这将超过10亿个。
然而,最多只需要3次磁盘IO就能读取到需要的数据到内存中。
相比于二叉树,它的优势在于它在查找的时候,每次能排除更多的无效数据,如果我们只需要查找一个数,二叉树每次只能排除1/2的无效数据,而上面提到的那棵BTree每次能排除1000/10001的数据。
BTree牺牲的是内存存储和计算,用此来换取更少的磁盘IO次数。
定义规则:
一棵M阶(M>=3)的B树,是一棵平衡的M路搜索树。它或者是空树,或者是满足下列性质的树:
1、根节点至少有两个子女;
2、每个非根节点所包含的关键字个数满足:[M/2 -1, M-1];(如果M为3,则每个非根节点上的关键字为[0,2],最多两个)
3、每个非根节点的出度正好是关键字总数+1 ;也就是说,3个关键字,将会有4个孩子,这3个关键字正好是4个孩子持有关键字的分界线;如图所示,这是一颗B+树的一部分:
关键字:30和40,将他们的三个子节点分为3段,每段都是按顺序排列的
4、所有的叶子都位于同一层;
5、每个节点的关键字都是按从小到大的顺序排列,
可以认为每个节点的所有数据都是一个连续的磁盘块,因为它是一次从磁盘中读取的,
每个节点有两部分数据:关键字 + 子节点指针;
每个节点的关键字个数是可以不一致的,只要满足条件就可以;
BTree的插入操作:
1、查找这个插入的数据是否已经存在,如果存在,则返回;
2、如果不存在,则将数据放在节点的顺序排列位置;
3、如果放置数据的节点的关键字个数已经满了,就将中间位置的数据往父节点的关键字部分添加;
4、如果父节点的关键字个数已经满了,就重复步骤3;
因为约束了根节点最少2个子节点,意思就是说根节点至少有一个关键字,树的高度不会变化;
- B+树
B+树是B树的一种变体,也是一种多路搜索树,它有如下更多的约束:
1、非叶子节点的子树指针与关键字个数相同;
2、非叶子节点的子树指针P[X],指向关键字属于[k[X],k[i+1])的子树;
3、只有叶子节点的关键字才是真正的数据
4、所有叶子节点都有一个链指针;
5、所有叶子节点都在同一层;
(只是一部分)
- 应用
B树和B+树经常被运用到数据库中,作为MySQL的数据库索引。
首先需要明确,索引是用来快速定位目标数据的;
一个简单的SQL:select name from t_a where id = 20;
首先从from语句开始解析,准备数据,从t_a表中取出id = 20的数据;然后再从数据中选择name字段;
如果id字段没有增加索引,就需要从开始到最后全部读出来,然后判断id是不是20,直到找到为止;
如果id字段增加了索引,则就会从承载索引的那颗B+树中找到id=20的节点,而后再定位到表数据;
哪种方式快?
不言而喻,第二种方式当然会比第一种要快,因为B+树的查找比起线性表,是快很多的;
关于MySQL的索引:
1、当定义一个主键时,MySQL的存储引擎把它当做一个聚集索引;
2、如果没有定义主键,则MySQL定位到第一个唯一索引,且该索引的所有列值均为非空的,则将其当做聚集索引;
3、如果没有主键或者适合做唯一索引,MySQL会生成一个隐藏的行ID值(6字节);
4、一个表中除了聚集索引,定义的都是辅助索引,也称为二级索引。
MySql的两套引擎,MyISAM和InnoDB,他们对索引的处理,有些差异;
MyISAM:
B+树叶子节点存储的是数据行的起始地址; 索引和数据是分开存的;
InnoDB 主索引:
InnoDB的数据和索引是放一起的;但是它的辅助索引,也是如此;所以MySQL的.ibd文件中,存储了表数据和索引信息;
了解完上面这些之后,一些关于InnoDB索引的问题,就有些眉目了:
1、一次查询只能用到一个索引;
因为索引是分开存的,不同的索引对应不同的数据;
2、尽量使用区分度高的列作为索引;
这很明显,区分度高,更有利于在树中的查找;
3、索引列不能参与计算;
索引列中保存的是表中的字段值,如果进行查找时还需要先把字段进行计算,开销太大;所以索引列做了函数操作之后,是不会走索引的;not、<>、!=亦是如此;
4、为什么索引越多,插入更新操作越慢?
索引越多,B+树越多,维护起来越费劲;
-EOF-
- B-Tree / B+Tree 结构以及MySQL索引
- mysql索引结构B+Tree结构
- Mysql B-Tree 索引
- mysql b-tree索引
- mysql b-tree索引
- 详解b+tree以及mysql索引 二
- Mysql InnoDB B+Tree索引
- 详解B+tree以及mysql的索引原理 一
- B-Tree B+Tree mysql索引(MyISAM,InnoDB)
- MySQL索引使用的数据结构:B-Tree和B+Tree
- MySQL索引使用的数据结构:B-Tree和B+Tree
- MySQL索引使用的数据结构:B-Tree和B+Tree
- mysql hash 索引 vs B-TREE 索引
- MYSQL 索引----B-Tree和全文索引
- mysql 索引类型详解-B-Tree索引
- 转储B*Tree索引的分枝结构!
- 理解mysql索引背后的数据结构B~Tree(B-Tree/B+Tree)
- B-Tree 索引
- java 多线程随记
- SwipyRefreshLayout+recyclerview
- TCP和UDP的最完整的区别
- repo的介绍
- 上传图片
- B-Tree / B+Tree 结构以及MySQL索引
- 【知了堂学习笔记】myBatis实现增删查改
- linux:破解navicat
- Tablayout
- Linux:mysql数据库的热备份,主从数据库搭建
- java集合list
- Hash Table -- Leetcode problem349. Intersection of Two Arrays
- PHP实现阶乘的原理与代码分析
- 标准C语言 IO