B+树的介绍
B+树的概念规则:
B+跟B树差异B+树的非叶子节点不保存关键字记载的指针,只举行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增长
B+树叶子节点保存了父节点的所有关键字记载的指针,所有数据地点必须要到叶子节点才气获取到。所以每次数据查询的次数都一样
B+树叶子节点的关键字从小到大有序分列,左边结尾数据都会保存右边节点开始数据的指针
非叶子节点的子节点数=关键字数(来源百度百科)(Mysql 的B+树)
B+树相比于B树的优点
由于B+树在内部节点上欠好含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子几点上关联的数据也具有更好的缓存命中率;
B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。而且由于数据次序分列并且相连,所以便于区间查找和搜索。而B树则需要举行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。
总结:B+树的I/O次数更少,磁盘读写代价更低,时间更稳固,范围搜索更好
B+树的存在情势
[*]结点内有n个元素就会n个子结点;每个元素是子结点元素里的最大值或最小值。
[*]结点内有n个元素就会n+1个子结点;最左边的子结点小于最小的元素,其余的子结点是>=当前元素。
B+树实现
以第一种情势实现
B+树节点参数
protected int degree;//阶数
protected BPlusNode<K,V> parent;//父节点
protected int keyNum;//关键字个数
protected LinkedList<K> keys;//存放数据项的list,K为key
protected boolean isLeaf;//是否为叶子节点
LinkedList<BPlusNode<K,V>> childList;//存放孩子节点list
public BPlusNode(int degree){
if (degree<3) throw new IllegalArgumentException("The BPlusTree degree must be at least three!");
this.degree = degree;
parent=null;
keys= new LinkedList<>();
childList= new LinkedList<>();
}
//查找
abstract BPlusNode<K,V> search(K key);
//删除
abstract BPlusNode<K,V> delete(K key);
//插入
abstract BPlusNode<K,V> insert(K key,V value);
//上溢
protected boolean isOverFlow(){
return keyNum >degree;
}
//下溢
protected boolean isUnderFlow(){
return keyNum<Math.ceil(degree/2.0);
}
```java
public V searchData(K key){
Objects.requireNonNull(key);
var search =(LeafNode<K, V>) root.search(key);
if (search.insertIndex<search.entryKey.size()){
var searchEntry = search.entryKey.get(search.insertIndex);
if (searchEntry.key().equals(key)) return searchEntry.value();
}
return null;
}
操作原理
[*]查找操作:从根节点开始,将待查找的关键字与当前节点的关键字举行比较。如果待查找的关键字小于当前节点的最小关键字,则沿着最左边的指针进入下一层节点继续查找;如果待查找的关键字大于当前节点的某个关键字,则沿着相应的指针进入下一层节点。重复这个过程,直到找到目标关键字地点的叶子节点。由于叶子节点之间是有序链表,因此在找到叶子节点后,可以方便地在链表中举行次序查找,以找到所有匹配的记载。
[*]插入操作:起首举行查找操作,找到合适的叶子节点位置。如果叶子节点未满,则直接将新的关键字插入到叶子节点中,并保持叶子节点的有序性;如果叶子节点已满,则需要对叶子节点举行分裂操作。将叶子节点均匀分成两部分,将中间关键字上移到父节点中,并在父节点中插入一个指向新分裂出的叶子节点的指针。如果父节点也已满,则需要对父节点举行雷同的分裂操作,直到找到一个未满的父节点或者到达根节点。如果根节点已满,则创建一个新的根节点,将原来的根节点分裂为两个子节点,并将中间关键字插入到新根节点中。
[*]删除操作:先通过查找操作找到要删除的关键字地点的叶子节点。如果该关键字地点的叶子节点中的关键字数量大于最小值(通常为分支因子的一半向上取整),则直接删除该关键字,并保持叶子节点的有序性;如果该叶子节点中的关键字数量便是最小值,且其左右兄弟节点中有一个节点的关键字数量大于最小值,则可以从兄弟节点中借一个关键字过来,或者将兄弟节点与该叶子节点归并。如果兄弟节点的关键字数量也都便是最小值,则需要将该叶子节点与一个兄弟节点归并,并将父节点中对应的关键字删除。如果父节点中的关键字数量小于最小值,则需要对父节点举行雷同的调整操作,直到满足 B + 树的布局要求。
上风
[*]高效的查找性能:由于 B + 树的高度相对较低,且叶子节点形成有序链表,因此无论是随机查找照旧范围查找,都能够在较短的时间内完成。
[*]支持次序访问:叶子节点之间的链表布局使得可以方便地举行次序访问,这对于需要按照次序处置处罚数据的应用场景非常有利,如范围查询、排序等。
[*]磁盘 I/O 优化:B + 树的节点通常较大,可以容纳多个关键字和指针,使得一次磁盘 I/O 能够读取更多的数据,从而减少磁盘 I/O 的次数,进步体系的整体性能。
应用场景
[*]数据库管理体系:用于存储和索引数据库中的表数据,如 MySQL、Oracle 等数据库都广泛使用 B + 树来实现索引布局,以进步数据的查询服从。
[*]文件体系:在文件体系中,B + 树可以用于存储文件目次信息,快速定位文件的存储位置,进步文件体系的性能。
MySQL中的B+树是怎么实现的:
MySQL 中的 B + 树重要是通过以下方式实现的:
数据布局定义
[*]节点布局:B + 树的节点通常包罗多个关键字和对应的数据指针。非叶子节点只存储关键字和指向下一层节点的指针,而叶子节点除了关键字外,还存储了现实的数据记载或者指向数据记载的指针。
[*]关键字有序分列:节点中的关键字按照从小到大的次序分列。这使得在查找、插入和删除操作时能够快速定位到目标关键字的位置。
查找操作实现
[*]从根节点开始,将待查找的关键字与节点中的关键字举行比较。
[*]如果待查找关键字便是当前节点的某个关键字,则根据该关键字对应的指针找到相应的数据记载。
[*]如果待查找关键字小于当前节点的最小关键字,则沿着最左边的指针继续查找下一层节点。
[*]如果待查找关键字大于当前节点的最大关键字,则沿着最右边的指针继续查找下一层节点。
[*]如果待查找关键字介于当前节点的两个关键字之间,则根据节点中关键字的分列次序,找到对应的指针,继续查找下一层节点,直到找到目标关键字或到达叶子节点确定不存在该关键字为止。
插入操作实现
[*]起首举行查找操作,找到合适的叶子节点来插入新的关键字。
[*]如果叶子节点未满,则直接将新关键字插入到合适的位置,保持关键字的有序性。
[*]如果叶子节点已满,则需要对该叶子节点举行分裂操作。将叶子节点中的关键字和数据指针均匀分成两部分,将中间关键字提拔到父节点中,并将新的关键字插入到合适的子节点中。如果父节点也已满,则需要递归地对父节点举行分裂操作,直到找到一个未满的父节点或者到达根节点。如果根节点也已满,则创建一个新的根节点,将原来的根节点分裂成两个子节点,并将中间关键字提拔到新的根节点中。
删除操作实现
[*]先通过查找操作找到包罗要删除关键字的叶子节点。
[*]如果要删除的关键字地点的叶子节点中的关键字数量大于最小关键字数量限制,则直接从该叶子节点中删除关键字,并调整关键字的次序以保持有序性。
[*]如果删除关键字后,叶子节点中的关键字数量小于最小关键字数量限制,则需要举行调整操作。可以从相邻的兄弟节点中借调关键字,或者与兄弟节点举行归并操作。如果相邻兄弟节点中的关键字数量足够,则可以将兄弟节点中的一个关键字移动到当前节点中,以保持节点的关键字数量平衡。如果相邻兄弟节点中的关键字数量也不足,则需要将当前节点和兄弟节点归并成一个新的节点,并将父节点中对应的关键字和指针举行相应的调整。如果父节点中的关键字数量小于最小关键字数量限制,可能需要递归地对父节点举行调整操作,直到满足 B + 树的平衡条件为止。
索引组织方式
[*]在 MySQL 中,B + 树索引是基于表中的列来创建的。对于差异的数据类型和索引类型,B + 树的实现细节会有所差异。比方,对于整数类型的索引列,关键字的比较和排序操作相对简单直接;而对于字符串类型的索引列,通常需要根据字符集和排序规则来举行比较和排序。
[*]聚簇索引和非聚簇索引在 B + 树的实现上也有一些差异。聚簇索引的叶子节点直接存储了数据记载,而非聚簇索引的叶子节点存储的是指向数据记载的指针。因此,在使用聚簇索引举行查找时,可以直接获取到数据记载,而使用非聚簇索引查找时,还需要根据指针再去查找相应的数据记载。
MySQL中索引实现原理:
MySQL 中的索引是一种用于进步查询服从的数据布局,着实现原理重要基于 B + 树等数据布局,以下是详细介绍:
B + 树数据布局基础
[*]节点布局:B + 树的节点包罗多个关键字和对应的数据指针。非叶子节点仅存储关键字与指向下一层节点的指针,用于引导搜索路径;叶子节点除关键字外,还存储现实的数据记载或指向数据记载的指针。
[*]关键字有序分列:节点内的关键字按从小到大的次序分列,便于快速查找、插入和删除操作时定位目标关键字。
索引的组织方式
[*]聚簇索引:基于表中某一列或多列组合构建。叶子节点直接存储数据记载,数据在物理存储上按聚簇索引列的值次序分列。一个表只能有一个聚簇索引,通常主键会被自动设为聚簇索引。如CREATE TABLE语句中使用PRIMARY KEY定义主键时,MySQL 会自动创建聚簇索引。
[*]非聚簇索引:叶子节点存储的是指向数据记载的指针,而非数据记载本身。一个表可以有多个非聚簇索引,可基于表中的其他列创建,用于加快对该列的查询。通过CREATE INDEX语句创建非聚簇索引,如CREATE INDEX index_name ON table_name (column_name);。
索引的查找过程
[*]从根节点开始,将查询条件中的关键字与节点中的关键字比较。若相等,则根据指针找到对应数据记载;若小于最小关键字,沿最左边指针找下一层节点;若大于最大关键字,沿最右边指针找下一层节点;若介于两个关键字之间,按次序找到对应指针继续查找,直至找到目标关键字或确定不存在。
索引的插入与维护
[*]插入操作:先查找合适的叶子节点插入新关键字。若叶子节点未满,直接插入并保持有序;若已满,则分裂节点,将关键字和指针均匀分成两部分,中间关键字提拔到父节点,新关键字插入合适子节点,若父节点也满,则递归分裂,直至找到未满父节点或到达根节点,根节点满则创建新根节点。
[*]删除操作:先找到包罗要删除关键字的叶子节点,若删除后关键字数量大于最小限制,直接删除并调整次序;若小于最小限制,则需调整,可从相邻兄弟节点借调关键字或归并节点,若兄弟节点关键字数量够,可移动一个关键字到当前节点,若都不足,则归并节点,并调整父节点关键字和指针,若父节点关键字数量不足,需递归调整,直至满足 B + 树平衡条件。
差异数据类型的索引实现特点
[*]整数类型:比较和排序操作简单直接,索引查找服从高。
[*]字符串类型:需根据字符集和排序规则比较排序,字符集差异排序结果和索引布局可能差异,如 UTF-8 和 GBK 字符集对汉字的编码和排序方式有差异。
索引的优缺点及使用注意事项
[*]优点:大大进步查询速率,尤其对大数据量表和复杂查询条件,能快速定位数据,减少磁盘 I/O 操作,提拔数据库性能。
[*]缺点:占用额外存储空间,索引需存储关键字和指针等信息;插入、更新和删除操作时,需维护索引布局,增长数据操作时间本钱。
[*]注意事项:并非列都适合建索引,如数据重复度高的列建索引效果差;索引列应选常用于查询条件、毗连条件和排序条件的列;定期分析查询语句实行计划,根据现真相况调整索引,以保证索引的有用性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]