数据结构与算法-BtreeB+Tree

news2025/9/15 18:23:41

       一:引入

         作为一个IT从业者大家对数据库肯定是都知道的,大家应该知道在数据库中有个索引,在一张表中用了索引与不用索引那查找效率简直就是天壤之别,但是大家有没思考过,你经常用的索引是什么样的数据结构呢?它为什么又能这么高效的查找呢?究竟使用了什么样的算法呢?

        select * from user where  user_id = 100

        select * from user where  user_id  > 10

        select * from user where  user_id = 100  and name = “ykw”

 如果是你你该如何利用我们已经学过的知识来设计上面这个sql的索引结构呢?

        二:改造二叉查找树

        改造二叉搜索树: 大家看我改造后的二叉搜索树,

        执行 select * from table where id = 10

        执行 select * from table where id > 12

        select * from table where id > 12 and  id < 20

二叉查找树

        效果:  能解决我们上面所有的sql语句; 效率 logn 2^32=21亿;

        IO:指的是从磁盘读取数据。32层就要读取32次。CPU,内存,IO;

        IO从磁盘读一次会读多少数据?计算机组成原理。Page的。页,4KB。

        Int占多少空间?4B

        通过以上可知我们能够把sql语句的功能都能实现,而且效率也很高,那是不是这种结构 就可以作为mysql的索引了呢? 大家想想,右边这个结构我们是存在哪里的?有什么问题?怎么解决?

        问题1:搜索效率:32次

        问题2:查询次数:

        问题3:磁盘IO:解决这个问题;引出Btree

二叉查找树的改进:B+Tree

       

        所以为了让我们磁盘的存储效率达到最高利用率,就引入了B+Tree,B+树只在叶子节点中存储键值,非叶子节点中只存储键值的索引。B+树的叶子节点通过指针进行连接,使得数据的遍历更加高效。也可以是M阶B+Tree。

三:M阶B+Tree

     B+Tree的性质:  

        M阶的B+Tree:叉树

        (1)每个节点最多有m个子节点

        (2)除根节点外,每个节点至少有m/2个子节点,注意如果结果除不尽,就向上取整,比如5/2=3。 3/2=ceil(1.5)=2

        (3)根节点要么是空,要么是独根,否则至少有2个子节点

        (4)有k个子节点的节点必有k个关键码:就是 有m个数据就有m个叉叉;

        (5)叶节点的高度一致:这个的 好处是什么? 满树?连续?(为了保证我的将来查询的次数是相同的,不会因为变量的改变而改变。)

B+tree数据结构

四:mysql下的B+tree

     2.1  B+Tree在Mysql中的分析

                1.阶数:通过上面的分析我们知道这个阶数很重要直接决定了B+Tree的查找效率以及性能,那么在Mysql中我们如何设定这阶数呢?

                 通过mysql的页大小决定,一般是16k。那么一个主键类型为bigint的字段建索引大约的消耗空间是多少呢?

        Int:8字节,指针一个也算4字节。

        一页的节点:16kb/ (8b+8b)=1k 键值+指针 我们刚举例的3阶B+Tree你们计算下可以存多少索引值? 1024*1024*1024=多少?

可想而知如果在理想情况下 我们的mysql查询是不是很高效,一般最多也就4阶左右的B+Tree。

        

     2.2、具体计算方法

        2.1、根节点计算

首先我们只看根节点,假设我们设置的数据类型是bigint,大小为8b,在数据本身还有一小块空间,用来存储下一层索引数据页的地址,大小为6kb。所以我们可以计算出来一个数据为(8b+6b=14b)的空间(以bigint为例)。

我们刚才说到一个数据页的大小是16KB,也就是(16*1024)b,那么根节点是可以存储(16*1024/(8+6))个数据的,结果大概是1170个数据。

        2.2、其余层节点计算

第二层的数据量是1170*1170=1368900,问题在于第三层,因为innodb的叶子节点,是直接包含整条mysql数据的,如果字段非常多的话数据所占空间是不小的,我们这里以1kb计算,所以在第三层,每个节点为16kb,那么每个节点是可以放16个数据的,所以最终mysql可以存储的总数据为1170*1170*16=21902400(千万级条)。

        3、总结

综上,我们通过计算得出,MySQL一张表的最大数据量为21902400(千万级条)。实际上,一般在MySQL的一张表中超过了千万数据,我们就会考虑进行分表操作了。

  2.3 根据我们所学的数据结构知识,我们应该如何正确的建立索引:

        1.索引不能太多,因为B+tree的插入和删除是要维护的,太多的索引会导致插入变慢。         2.建了索引的字段不能使用like ‘%%’否则是失效的

        3.建索引的字段类型不能太大,字段越小阶数就越大,效率就越高,int 和 bigint,varchar(10),varchar(100),text,lontext;B+Tree。全文索引

        4.建索引的字段值不能太多一样的,数学里面有个叫什么散列多一些(离散),比如我们把性别建索引会出现啥情况?左边都是一样的值 过滤不了一半。User sex单独建索引 0 1         5.联合索引的最左匹配原则。当创建联合索引时,索引由多个列组成,例如(A, B, C),其中A是最左边的列,B是中间的列,C是最右边的列。在使用该联合索引进行查询时,MySQL会优先使用索引的最左边的列进行匹配,然后再根据需要使用中间列和最右边的列进行进一步的筛选。 这意味着,如果查询只涉及到了联合索引的最左边的列,那么索引将可以被完全利用,进行高效的查询。但是,如果查询中包含的列不是索引的最左边的列,那么索引的效果将会减弱,甚至可能不被使用。 举个例子,如果有一个联合索引 (A, B, C),而查询条件只包含了列A,那么索引将会被完全利用。但如果查询条件只包含了列B或C,那么索引的效果将会减弱,可能需要进行全表扫描。

        6.NOT IN 是不会走索引的 not in (1,2,3) In的值太多 mysql会报错的。上线的

五:小结

        二叉查找树,红黑树,B-Tree,B+Tree 的区别:

           二叉查找树:二叉搜索树,优点查找快,但是在某些情况下会退化成链表,它是所有 高效查找树的基础,如果不懂这个 其他的也学不懂。根本性的东西,最好能自己手写出来。

           红黑树:内存查找高效树,不适合大数据量 也不适合磁盘存储的。具体的分析就是IO浪费以及读取资源浪费,还有就是树的深度会很大。适合一些底层系统做内存运算

           B-Tree:所有的节点都会存数据,可以认为是B+Tree过度。只需要知道BTree就可以

           B+Tree:最适合大数据的磁盘索引,经典的MySql,所有的数据都存在叶子节点。其他都是索引,增加了系统的稳定性以及遍历以及查找效率 不同:关键字和Key值。数据存储的地方,双向链表。

           M阶:这个由磁盘的页面大小决定,磁盘快和页内存都是4KB。我们的节点数也就是我们的M值 应该要尽可能的跟他一样。1 0.75的原则HashMap。这样的好处就是为了我们一次刚好能全部拿出一个节点里面存的所有的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/997197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity中Shader抓取屏幕并实现扭曲效果

文章目录 前言一、屏幕抓取&#xff0c;在上一篇文章已经写了二、实现抓取后的屏幕扭曲实现思路&#xff1a;1、屏幕扭曲要借助传入 UV 贴图进行扭曲2、传入贴图后在顶点着色器的输入参数处&#xff0c;传入一个 float2 uv : TEXCOORD&#xff0c;用于之后对扭曲贴图进行采样3、…

SAP 创建动态内表

创建动态内表 一、根据表名创建内表 程序代码&#xff1a; "复杂方式 SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001. PARAMETERS:p_tab TYPE string. SELECTION-SCREEN END OF BLOCK b1.DATA:lr_struct TYPE REF TO data,lr_table TYPE REF TO data. …

【云原生系列】Docker学习

目录 一、Docker常用命令 1 基础命令 2 镜像命令 2.1 docker images 查看本地主机的所有镜像 2.2 docker search 搜索镜像 2.3 docker pull 镜像名[:tag] 下载镜像 2.4 docker rmi 删除镜像 2.5 docker build 构建镜像 3 容器命令 3.1 如拉取一个centos镜像 3.2 运行…

.env文件详解

.env配置文件 vue会根据 process.env.NODE_ENV 的值&#xff0c;自动加载对应的环境配置文件 .env 全局默认配置文件&#xff0c;在所有的环境中被载入;.env.production 生产环境文件 production;.env.development 开发环境文件 development&#xff1b;.env.test/.env.stagi…

从零开始完整实现-循环神经网络RNN

一 简介 使用 pytorch 搭建循环神经网络RNN&#xff0c;循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一类用于 处理序列数据的神经网络架构。与传统神经网络不同&#xff0c;RNN 具有内部循环结构&#xff0c;可以在处理序列数据时保持状态…

MySQL基础篇:掌握数据库基本操作,轻松上手

查看和指定现有的数据库 mysql> show databases; -------------------- | Database | -------------------- | information_schema | | bjpowernode | | eladmin | | mysql | | performance_schema | | sqlalchemy | | s…

makefile之使用函数wildcard和patsubst

Makefile之调用函数 调用makefile机制实现的一些函数 $(function arguments) : function是函数名,arguments是该函数的参数 参数和函数名用空格或Tab分隔,如果有多个参数,之间用逗号隔开. wildcard函数:让通配符在makefile文件中使用有效果 $(wildcard pattern) 输入只有一个参…

Qt串口基本设置与协议收发

前言 1.一直都想要做一个Qt上位机&#xff0c;趁着这个周末有时间&#xff0c;动手写一下 2.comboBox没有点击的信号&#xff0c;所以做了一个触发的功能 3.Qt的数据类型很奇怪&#xff0c;转来转去的我也搞得很迷糊 4.给自己挖个坑&#xff0c;下一期做一个查看波形的上位…

Java输入-a,-b,geek,-c,888,-d,[hello,world]字符之后,如何将[hello,world]这个不分开

Java输入-a,-b,geek,-c,888,-d,[hello,world]字符之后&#xff0c;如何将[hello,world]这个不分开&#xff1f; 你可以使用命令行参数解析库来处理Java输入中的各个参数。在这种情况下&#xff0c;你可以使用Apache Commons CLI库来解析命令行参数。以下是一个示例代码片段&am…

MATLAB遗传算法求解生鲜货损制冷时间窗碳排放多成本车辆路径规划问题

MATLAB遗传算法求解生鲜货损制冷时间窗碳排放多成本车辆路径规划问题实例 1、问题描述 已知配送中心和需求门店的地理位置,并且已经获得各个门店的需求量。关于送货时间的要求,门店都有规定的时间窗,对于超过规定时间窗外的配送时间会产生相应的惩罚成本。为保持生鲜农产品的…

2023.09.10 学习周报

文章目录 摘要文献阅读1-1 题目1-2 创新点1-3 本文工作2-1 题目2-2 什么是图2-3 图神经网络2-4 信息传递3-1 题目3-2 创新点3-3 本文工作 深度学习1.GNN的构建步骤2.构建图的方法3.GNN的简单样例 总结 摘要 本周阅读了三篇文章&#xff0c;第一篇是基于物理信息深度学习和激光…

【LeetCode题目详解】第九章 动态规划part11 ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV (day50补)

本文章代码以c为例&#xff01; 一、力扣第123题&#xff1a;买卖股票的最佳时机 III 题目&#xff1a; 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1…

基于springboot+vue的在线课程学习网站(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

unity实现Perlin噪声

Perlin噪声目的是为了生成连续变化的随机值。这里推荐一个使用unity实现的perlin噪声插件&#xff0c;包含源码&#xff0c;源码下载地址&#xff1a;https://download.csdn.net/download/hulinhulin/88323641https://download.csdn.net/download/hulinhulin/88323641 插件界面…

vscode 下载安装

vscode 下载安装常用插件 vscode 官网&#xff1a; https://code.visualstudio.com/ 点击右上角 Download 进入下载选择页面 选择自己使用操作对应 CPU 架构 下载 本文使用 x86 架构 64位 windows 系统为例 跳转下载页面 自动 开始下载 下载不开始&#xff1f;试试这个直…

关于黑马hive课程案例FineBI中文乱码的解决

文章目录 问题描述情况一的解决情况二的解决 ETL数据清洗知识社交案例参考代码结果展示 问题描述 情况1&#xff1a;FineBI导入表名中文乱码&#xff0c;字段内容正常情况2&#xff1a;FineBI导入表字段中文乱码&#xff0c;表名内容正常 情况一的解决 使用navcat等工具连接…

第九章 Linux实际操作——Linux磁盘分区、挂载

第九章 Linux实际操作——Linux磁盘分区、挂载 9.1 Linux分区9.1.1原理介绍9.1.2 硬盘说明9.1.3 查看所有设备搭载情况 9.2 挂载的经典案例9.2.1 说明9.2.2 如何增加一块硬盘9.2.3 虚拟机增加硬盘步骤 9.3 磁盘情况查询9.3.1 查询系统整体磁盘使用情况9.3.2 查询指定目录的磁盘…

TypeScript对象类型

废话不多说&#xff0c;还是挑点有营养的讲。 对象类型 1、匿名对象 匿名对象类型是在定义变量时直接使用花括号{}&#xff0c;来定义一个对象类型。 const person: { name: string, age: number } { name: John, age: 25 }; 2、接口类型 使用接口来定义对象类型&#x…

二叉树的顺序结构以及堆的实现——【数据结构】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 上篇文章&#xff0c;我们认识了什么是树以及二叉树的基本内容、表示方法……接下来我们继续来深入二叉树&#xff0c;感受其中的魅力。 目录 二叉树的顺序结构 堆的概念及结构 堆的实现 堆的创建 堆的初始化与…

LeetCode(力扣)455. 分发饼干Python

LeetCode20. 有效的括号 题目链接代码 题目链接 https://leetcode.cn/problems/assign-cookies/ 代码 从大遍历 class Solution:def findContentChildren(self, g: List[int], s: List[int]) -> int:g.sort()s.sort()index len(s) - 1result 0for i in range(len(g) -…