数据库浅谈之常见树结构

news2024/9/23 7:27:22

数据库浅谈之常见树结构

HELLO,各位博友好,我是阿呆 🙈🙈🙈

这里是数据库浅谈系列,收录在专栏 DATABASE 中 😜😜😜

本系列阿呆将记录一些数据库领域相关的知识 🏃🏃🏃

OK,兄弟们,废话不多直接开冲 🌞🌞🌞


一 🏠 概述

多路查找树

二叉树中每个节点中包含一个信息,如果节点数多,路径就会很深。即查询时经过了更多节点,造成性能下降


B 树

2-3 树 是最简单的 B 树结构,有如下特点

① 2-3 树所有叶节点都在同一层( B 树均满足该条件)

② 有两个子节点的节点叫二节点,二节点要么没有子节点,要么有两个子节点

③ 有三个子节点的节点叫三节点,三节点要么没有子节点,要么有三个子节点

④ 2-3树是由二节点和三节点构成的树

2-3 树插入规则

按照规则插入一个数到某个节点,若不满足上面 ① ② ③ ,则进行拆分;

先拆上层,若上层满,则拆本层,拆后仍需要满足上面 3 个条件

注 :三节点子树的值大小仍遵守(二叉排序树)规则

B 树的搜索

从根结点开始,对有序序列进行二分查找,命中则结束,或直至叶子结点(叶节点和非叶节点都存放数据,搜索等价于在全集内做二分)

B 树的优点

① 内部通过分裂机制,保持数据有序,重新组织节点,降低树高度提升效率

② 每个节点大小设为 4 K (一页大小) ,只需要一次 I/O 即可完全载入

③ 树高度为 1024,600 亿个元素最多只需要 4 次 I/O 即可读取到想要的元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jus8YqUf-1676805067472)(E:\2022年MD文档\2023 年 MD文档\二月\数据库浅谈\数据库浅谈之常见树结构.assets\055ecb1484d8a4c0b4de31753ba9fea0.png)]

B 树的场景

适合于单点查询,例如 MongoDB

缺陷 :所有节点都在磁盘上,读写性能差;不适合进行范围查找(可能在多个节点反复横跳)


B+ 树

它是 B 树的变体,也是一种多路搜索树

B+ 树性质

① 关键字均在叶结点链表中,且有序

② 不可能在非叶结点命中

③ 非叶子结点是叶结点索引,叶结点是存储关键字的数据层

④ 更适合文件索引系统

B 树和 B+ 树有各自应用场景,不能说B+树完全比B树好,反之亦然

非叶节点中仅保留数据之间的相对关系,而所有的真实信息均包含在叶子节点中。把相对关系信息放到内存中,而将所有节点信息(数据)保留在磁盘

查询时通过相对关系,在内存中快速定位到具体节点,从而减少磁盘 IO 次数。另一个优点是通过链表将所有叶节点串联,方便范围查询(例 MySql 存储引擎 InnoDB )


B+ 树信息存放在磁盘中,且属于非顺序写入,所以查询性能很高,但写入性能偏低。在大数据存储和日志服务等需要频繁写入操作领域,就不合适了


B* 树

B+ 树变体,树非根和非叶结点增加指向兄弟的指针,将结点最低利用率从 1/2 提高到 2/3

B+ 树分裂 :当一个结点满时,分配一个新结点,并将原结点中 1/2 数据复制到新结点,最后在父结点中增加新结点的指针;B+ 树分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;

B* 树分裂 :当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制 1/3 的数据到新结点,最后在父结点增加新结点的指针;

所以,B* 树分配新结点的概率比 B+ 树要低,空间使用率更高


字典树

又称单词查找树,Trie 树 ,是哈希树的一种变种。典型应用是用于统计,排序和保存大量的字符串,所以常被搜索引擎系统用于文本词频统计

优点:利用字符串公共前缀来减少查询时间,最大限度减少无谓字符串比较,查询效率比哈希树高

三个基本性质:

根节点不包含字符,除根节点外每一个节点都只包含一个字符

从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串

每个节点的所有子节点包含的字符都不相同


二 🏠 核心

跳表简单介绍(Skip List)

下图是一个简单有序单链表,查找某个数据,只能从头至尾遍历链表,时间复杂度是 O(n)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VI7qqpyy-1676805067474)(E:\2022年MD文档\2023 年 MD文档\二月\数据库浅谈\数据库浅谈之常见树结构.assets\1676804542873.png)]

对链表进行改造,先对链表中每两个节点建立第一级索引,再对第一级索引每两个节点建立第二级索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-343RY1h2-1676805067474)(E:\2022年MD文档\2023 年 MD文档\二月\数据库浅谈\数据库浅谈之常见树结构.assets\1676804621310.png)]

对于上图中的带二级索引的链表中,查询元素 16,先从第二级索引查询 1 -> 7->13,发现 16 大于 13 ,然后通过 13 的 down 指针找到第一级索引的 17,发现 16 小于17 ,再通过13 的 down 指针找到链表中的 16,只需要遍历 6 个节点就完成 16 的查找。

如果在单链表中直接查找 16 的话,只能顺序遍历,需要遍历 10 个节点,效率上有所提升


LSM树(日志结构合并树)

它是基于 Big Table 衍生出的一系列算法操作集合( 磁盘顺序写 + 多个树 ( 状数据结构 ) + 冷热(新老)数据分级 + 定期归并 + 非原地更新),描述了将实时产生的大批量信息在内存中排序、更新,然后按批次顺序写入磁盘固化、合并的流程,实现海量数据的高效存储( RocksDB、LevelDB、HBase )

B+ 树不适合频繁写入,因为它属于非顺序写入,而由于传统磁盘扇区结构,顺序写入性能远好于非顺序写入;相比于 B/B+ 树或者倒排索引,LSM Tree 采用了磁盘顺序写方案,因此具有极高的写吞吐量


数据结构定义

1、LSM 树 横跨内存和磁盘,包含多颗 子树 的森林(分为 Level 0,Level 1,Level 2 … Level n 多颗子树,其中只有Level 0在内存中,其余Level 1-n在磁盘中)

2、内存中 Level 0 子树一般采用排序树(红黑树/AVL树)、跳表等有序数据结构,方便后续顺序写磁盘

3、磁盘中的 Level 1-n 子树,本质是数据排好序后顺序写到磁盘上的文件,只是叫做树而已

4、每一层的子树都有一个阈值大小,达到阈值后会进行合并,合并结果写入下一层

5、只有内存中数据允许原地更新,磁盘上数据的变更只允许追加写,不做原地更新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o90ZK2kI-1676805067475)(E:\2022年MD文档\2023 年 MD文档\二月\数据库浅谈\数据库浅谈之常见树结构.assets\企业微信截图_16768026402676.png)]

  • 内存中的 Level 0树 在达到阈值后,会在内存中遍历排好序的 Level 0 树并顺序写入磁盘的 Level 1。同样的,在磁盘中的 Level n(n>0)达到阈值时,则会将 Level n 层的多个文件进行归并,写入 Level n+1 层
  • 除了内存中的 Level 0 层做原地更新外,对已写入磁盘上的数据,都采用 Append 形式的磁盘顺序写,即更新和删除操作并不去修改老数据,只是简单的追加新数据。右侧蓝色的磁盘部分,Level 1 和 Level 2 均包含 key 为 2 的数据,同时左侧绿色内存中的 Level 0 树也包含 key 为 2 的数据节点

LSM 增删改查

插入 :往内存中 Level 0 排序树丢即可,并不关心数据是否在内存或磁盘中存在(已存在则场景转换成更新操作)

删除 :并不是直接删除,而是通过 墓碑标记 的特殊数据来标识数据删除;

删除分为:待删除数据在内存中、待删除数据在磁盘中 和 该数据不存在 三种情况

修改 :和删除操作相似,也是分为三种情况:待修改数据在内存中、在磁盘中和 该数据不存在

查询 :按顺序查找 Level 0、Level 1、Level 2 … Level n ,一旦匹配则返回目标数据(策略保证查到的是最新版本数据,类似 MVCC )


LSM 合并

合并原因 :一 内存不是无限大,Level 0 树达到阈值时,需将数据从内存刷到磁盘中;二 需对磁盘上达到阈值的顺序文件进行归并,并将归并结果写入下一层,过程中会清理重复数据和被删除数据 (墓碑标记)


优缺点分析

优:增、删、改操作快,写吞吐量高

缺:读操作被弱化,不擅长区间范围读操作, 归并耗资源


LSM 树通过舍弃部分读性能,换取了高写性能,适用于写吞吐量远大于读吞吐量场景

设计原则 :

  1. 先内存再磁盘
  2. 内存原地更新
  3. 磁盘追加更新
  4. 归并保留新值

三 🏠 结语

身处于这个浮躁的社会,却有耐心看到这里,你一定是个很厉害的人吧 👍👍👍

各位博友觉得文章有帮助的话,别忘了点赞 + 关注哦,你们的鼓励就是我最大的动力

博主还会不断更新更优质的内容,加油吧!技术人! 💪💪💪

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

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

相关文章

metasploit穷举模块

目录 工具介绍 常用模块 参数介绍 工具使用 工具介绍 Metasploit框架(Metasploit Framework, MSF)是一个开源工具, 旨在方便渗透测试,它是由Ruby程序语言编写的模板化框架,具有很好的扩展性,便于渗透测试人员开发、使用定制的…

浅析C++指针与引用,栈传递的关系

目录 前言 C 堆指针 栈指针 常量指针 指针常量 引用 常量引用 总结 前言 目前做了很多项目,接触到各种语言,基本上用什么学什么,语言的边际就会很模糊,实际上语言的设计大同小异,只是语言具备各自的特性区别。…

Python学习-----模块3.0(正则表达式-->re模块)

目录 前言: 导入模块 1.re.match() 函数 (1)匹配单个字符 (2)匹配多个字符 (3) 匹配开头和结尾 2.re.search() 函数 3.re.findall() 函数 4.re.finditer() 函数 5.re.split() 函数 6.re.sub() 函数 7.re.sub…

JAVA BIO,NIO,AIO区别(建议收藏)

Java中的IO原理 首先Java中的IO都是依赖操作系统内核进行的,我们程序中的IO读写其实调用的是操作系统内核中的read&write两大系统调用。 操作系统内核是如何进行IO交互的呢? 网卡中的收到经过网线传来的网络数据,并将网络数据写到内存…

Flink01: 基本介绍

一、什么是Flink 1. Flink是一个开源的分布式,高性能,高可用,准确的流处理框架 (1)分布式:表示flink程序可以运行在很多台机器上, (2)高性能:表示Flink处理性…

LabVIEW使用实时跟踪查看器调试多核应用程序

LabVIEW使用实时跟踪查看器调试多核应用程序随着多核CPU的推出,开发人员现在可以在LabVIEW的帮助下充分利用这项新技术的功能。并行编程在为多核CPU开发应用程序时提出了新的挑战,例如同步多个线程对共享内存的并发访问以及处理器关联。LabVIEW可自动处理…

基于SpringBoot+vue的无偿献血后台管理系统

基于SpringBootvue的无偿献血后台管理系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背…

基于BIM技术建设的重庆来福士广场项目

1. BIM工程应用概况 1.1 工程概况 重庆来福士广场项目位于朝天门广场与解放碑之间,直面长江与嘉陵江交汇口。是集大型购物中心、高端住宅、办公楼、公寓式酒店和酒店为一体的综合体项目。由于本项目钢结构体量大、结构复杂,混凝土标号高、强度大…

树莓派centos7.9(armv7hl)安装最新版宝塔linux面板 2023-0219

内存卡或usb存储器容量建议不小于16GB 1.启用 EPEL 软件源 树莓派安装centos7.9(armv7hl)以及宝塔linux面板. 2023-2-16_mklpo147的博客-CSDN博客 2.使用gcc-6 树莓派centos7.9(armv7hl)安装并切换GCC-6版本. 2023-2-18_mklpo147的博客-CSDN博客 3.更新系统 yum install -y e…

第1讲-初步认识数据库系统(测试题总结)

一、测试题 数据库系统 包含 数据库管理系统 详细版: 数据库管理系统DBMS是数据管理软件,在用户和操作系统之间。 数据库系统DBS由数据库,数据库管理系统(及其应用开发工具)、应用程序和数据库管理员DBA组成的存储、管…

使用51单片机的GPIO输出占空比可调节的PWM波

一、前言 在一些单片机或微控制器中,通用GPIO可以被配置为产生PWM信号。PWM即脉冲宽度调制,是一种用于模拟输出的技术。它可以通过改变输出信号的脉冲宽度来控制电路中的电平,从而实现对电路的控制。 二、什么是PWM波? PWM波&a…

JavaSE-线程池(5)- 建议使用的方式

JavaSE-线程池(5)- 建议使用的方式 虽然JDK Executors 工具类提供了默认的创建线程池的方法,但一般建议自定义线程池参数,下面是阿里巴巴开发手册给出的理由: 另外Spring也提供了线程池的实现,比如 Thread…

Flink02:Flink快速上手(Streaming WorldCount)

一、Flink快速上手 使用 (1)先把Flink的开发环境配置好。 (2)创建maven项目:db_flink (3)首先在model中将scala依赖添加进来。 (4)然后创建scala目录,因为针…

Lesson5---NumPy科学计算库

5.1 多维数组 Python拥有出色的第三方库生态系统在机器学习中,需要把所有的输入数据,都转变为多为数组的形式。score[i, j]二维数组i,j都从0开始 score[5] [85, 72, 61, 92, 80] score[2,5] [[85, 72, 61, 92, 80],[85, 72, 61, 92, 80]] score[30,5…

Linux系统之iptables应用SNAT与DNAT

目录 SNAT 一.SNAT的原理介绍 1.应用环境 2.SNAT原理 3.SNAT转换前提条件 二.开启SNAT 1.临时打开 2.永久打开 三.SNAT的转换 1.固定的公网IP地址 2.非固定的公网IP地址(共享动态IP地址) 四.SNAT实验 1.实验环境准备 2.配置web服务器(192.168.100.100…

测试3.测试方法的分类

3.测试分类 系统测试包括回归测试和冒烟测试 回归测试:修改了旧的代码后,重新测试功能是否正确,有没有引入新的错误或导致其它代码产生错误 冒烟测试:目的是确认软件基本功能正常,可以进行后续的正式测试工作 按是否…

什么是 RESTful 风格?

一、什么是 REST ? REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Thomas Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式&#…

游戏开发 - 开发流程 - 收集

1.应用场景 主要用于了解,掌握游戏开发的整个流程。 2.学习/操作 1.文档阅读 复习课 | 带你梳理客户端开发的三个重点-极客时间 2.整理输出 2.1 游戏开发流程 -- 参考 按照游戏开发中的三大模块策划、程序、美术,画了一个图。 开发游戏的时候&#xff…

LeetCode171-Excel表列序号(进制转换问题)

LeetCode171-Excel表列序号1、问题描述2、解题思路:进制转换3、代码实现1、问题描述 给你一个字符串columnTitle,表示Excel表格中得列名称。返回该列名称对应得列序号。 例如: A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 …

linux shell 入门学习笔记3 shebang

shebang 计算机程序中,shebang指的是出现在文本文件的第一行前两个字符#! 在Unix系统中,程序会分析shebang后面的内容,作为解释器的指令,例如 以#!/bin/sh 开头的文件,程序在执行的时候会调用/bin/sh,也就…