MySQL索引树(B树和B+树)理解

目录

BTree

B树的阶

B树的根

B树的内部节点

B树的叶子节点

B树的插入

B树的删除操作

磁盘的IO

B+树

索引结构类型

按数据结构分类

hash索引

FullText索引

RTree

按物理存储分类:

按字段特性分类:

按字段个数分类:

为什么B+树更适合用来做数据库索引树?


BTree

一个多路平衡二叉树,出自于AVL树,但是AVL树的高度太高,查询效率太低

注意:m也就是B树的阶,至于B树的阶如何确定,那么就需要看B树子节点允许存在的最大子孩子(子树)的数量,允许节点存在m-1个关键字。

        每个节点最多只有m个子节点。

        每个非叶子节点(除了根)具有至少⌈ m/2⌉子节点。

        如果根不是叶节点,则根至少有两个子节点。

        具有k个子节点的非叶节点包含k -1个键。

        所有叶子都出现在同一水平,没有任何信息(高度一致)。

B树的阶

B树中,一个节点的子节点数目最大值

B树的根

也就是最顶端那一个节点,如果根节点并非树中唯一节点,那必须有两个子节点,要不然就成为了单支节点

B树的内部节点

就是除根节点和叶子节点之外的所有节点

B树的叶子节点

B树的最后一层节点,没有子节点,也没有指向子节点的指针

B树的插入

B树插入m阶B树时,如果该节点的元素个数小于m则直接插入,

如果节点的个数大于或者等于m,则会先分裂,取节点的中间元素插入到父节点中(偶数,取中间两个数的随机一个),然后将元素插入

最坏的情况就是一直分裂到根节点,树的高度加一

B树的删除操作

如果B树中的某个节点的元素数目小于(m/2)-1,m/2向上取整,这时需要看相邻节点的数量是否满足(m/2)-1,如果满足,直接向父节点借一个元素,如果不满足,则两个节点合并

磁盘的IO

磁盘的IO读写的花费时间分为三个部分寻道时间+旋转延迟和传输时间,寻道指的是磁臂移动到指定磁道所花费的时间,旋转延迟是指磁盘的转速,比如磁盘转速为7200r,那么每分钟就是7200r,每秒就是120r,旋转延迟也就是转一圈就是4.17ms,传输时间是指将数据读出或者写入的时间。

在数十亿条并发指令下,计算机资源尤为昂贵,所以,提出了内缓存区,在数据读取时,也会将相邻数据读到内缓存区中,每次IO读写都是一个数据块,在数据库中称为一页,页的大小和操作系统有关,有的4K,有的16K

B+树

有m个子树的中间节点包含有m个元素(B树中是k-1个元素),每个元素不保存数据,只用来存取索引;


所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接。 (而B 树的叶子节点并没有包括全部需要查找的信息);


所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息);

索引结构类型

按数据结构分类

B+tree索引、Hash索引、Full-text索引、Rtree索引。

BTree索引、Hash索引、full-text索引、R-Tree索引

BTree索引在上边已经介绍

hash索引

也就是采用hash表的结构,k-v键值对的形式,所以对于数据的检索效率是非常高的,

但是hash索引无法支持范围查询,应为hash内部的key是无序的,没有办法利用,那么hash索引自然也不支持order by  

hash索引无法支持联合索引的最左匹配原则,因为hash是将多个索引键键合并在一起计算hash值,不会针对单个索引键做计算,自然不支持联合索引,更不用说最左匹配

但是hash在做等值查询时的效率非常高

FullText索引

MySQL主要要来做搜索引擎,且只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引

select * from answer where match(字段) against("表名")

为了更好的所有效果,需要在mysql的配置文件做更改,也就是my.ini

// MyISAM
ft_min_word_len = 4; 默认值
ft_max_word_len = 84; 默认值

// InnoDB
innodb_ft_min_token_size = 3; 默认值
innodb_ft_max_token_size = 84; 默认值

//ngram解析器令牌长度----即against()中字符串切分的最小字符长度
ngram_token_size = 2~10 ; 默认值

一般设定:(以下例子均是假定设置如下)
在 [mysqld]的下面追加:
innodb_ft_min_token_size = 2
ft_min_word_len = 2
ngram_token_size = 2

修改后重启mysql服务,打开任务管理器,找到mysql服务,直接右键重启

使用如下语法,在命令行查看变量

show variables like "%ft%"
show variables like "%ngram%"

 使用语法

【+】----------必须包含此字符串

【-】----------必须不包含此字符串

【“ ”】--------双引号内作为整体不能拆词

【> 】--------提高该词的相关性,查询的结果靠前

【< 】--------降低该词的相关性,查询的结果靠后

【*】---------通配符,只能接在词后面

SELECT * FROM user WHERE MATCH(userName) AGAINST (‘+“张” & +“三” ’ IN BOOLEAN MODE);

RTree

空间索引,它将空间对象按范围划分,每个结点都对应一个区域和一个磁盘页,非叶结点的磁盘页中存储其所有子结点的区域范围,所以更适合做范围查询

但它仅支持geometry数据类型,支持该类型的存储引擎只有myisam、bdb、innodb、ndb几种。

索引又分为聚集索引和非聚集索引

按物理存储分类:

聚集索引、非聚集索引(也叫二级索引、辅助索引)。

按字段特性分类:

主键索引(PRIMARY KEY)、唯一索引(UNIQUE)、普通索引(INDEX)、组合索引、全文索引(FULLTEXT)。

按字段个数分类:

单列索引、联合索引(组合索引)

为什么B+树更适合用来做数据库索引树?

首先,B+树内部节点并没有存储指向关键字具体信息的指针,所以B+树的内部节点比B树的内部节点更小,在一页或块中,所能容纳更多的关键字信息

非终节点并不是最终指向文件内容的节点,而是指向叶子节点关键字信息的指针,所以任何关键字的查找都是需要从根节点到叶子节点的查询,所以查询效率基本相同

B+树更适合做范围查询,因为B+树中的关键字信息都是存放在叶子节点中,所以只需要遍历叶子节点就可以查找到所有元素(B树用的是中序遍历,B+树是链表遍历)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羊驼有点累

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值