惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
Scott Helme
Scott Helme
NISL@THU
NISL@THU
Cisco Talos Blog
Cisco Talos Blog
C
Cybersecurity and Infrastructure Security Agency CISA
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
J
Java Code Geeks
U
Unit 42
The GitHub Blog
The GitHub Blog
H
Help Net Security
T
Tenable Blog
aimingoo的专栏
aimingoo的专栏
Jina AI
Jina AI
Spread Privacy
Spread Privacy
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理
L
Lohrmann on Cybersecurity
T
Threatpost
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Engineering at Meta
Engineering at Meta
A
About on SuperTechFans
I
InfoQ
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog
L
LINUX DO - 最新话题
K
Kaspersky official blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threat Research - Cisco Blogs
C
Check Point Blog
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
Y
Y Combinator Blog
N
News | PayPal Newsroom
M
MIT News - Artificial intelligence
Latest news
Latest news
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
腾讯CDC
I
Intezer
爱范儿
爱范儿
F
Fortinet All Blogs
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes

青空之蓝

[青空之蓝-2023] - 色彩 | 青空之蓝 [青空之蓝-2022] - 平静 | 青空之蓝 [青空之蓝-2021] - 远望 | 青空之蓝 浅谈垃圾回收 | 青空之蓝 浅谈泛型擦除 | 青空之蓝 浅谈单点登录 | 青空之蓝 使用 Kotlin 编写 Spring 测试 | 青空之蓝 设计模式系列文章 | 青空之蓝 从零实现一个 Java 微框架 - IoC | 青空之蓝 从零实现一个 Java 微框架 - 前言 | 青空之蓝 浅谈 JVM:类加载 | 青空之蓝 浅谈 IO | 青空之蓝 浅谈并发:synchronized & ReentrantLock | 青空之蓝 浅谈并发:CAS & AQS | 青空之蓝 浅谈并发:ThreadLocal | 青空之蓝 浅谈并发:三大特性 | 青空之蓝 浅谈组合注解 & 注解别名 | 青空之蓝 [青空之蓝-2020]-迷茫 | 青空之蓝 Java 系列文章 | 青空之蓝 HTTP 系列文章 | 青空之蓝 浅谈 EatWhatYouKill | 青空之蓝 浅谈可扩展线程池 | 青空之蓝 聊聊写框架 | 青空之蓝 聊聊现状-[2020-09] | 青空之蓝 浅谈并发:锁 | 青空之蓝 浅谈并发:基础 | 青空之蓝 浅谈缓存 | 青空之蓝 无须定义类,Spring 快速注入 Json 参数 | 青空之蓝 浅谈 Proxy 和 Aop | 青空之蓝 从零实现一个 PHP 微框架 - 初始化请求 | 青空之蓝 为 Vue3 添加一个简单的 Store | 青空之蓝 从零实现一个 PHP 微框架 - 服务提供者 | 青空之蓝 WSL2 踩坑记录 | 青空之蓝 浅谈浏览器Event Loop [更新] | 青空之蓝 从零实现一个 PHP 微框架 - Bootstrap 启动加载 | 青空之蓝 从零实现一个 PHP 微框架 - IoC 容器 | 青空之蓝 从零实现一个 PHP 微框架 - PSR & Composer | 青空之蓝 从零实现一个 PHP 微框架 - 前言 | 青空之蓝 MVVM 简单实现 | 青空之蓝 浅谈 DI 和 IoC | 青空之蓝 中间件实现 [PHP] | 青空之蓝 告别 Windows 终端的难看难用,打造好用的 PowerShell | 青空之蓝 VSCode Java输出中文乱码问题解决[更新] | 青空之蓝 浅谈浏览器渲染 | 青空之蓝 Vue-Cli@2 项目迁移日志 | 青空之蓝 Laragon & Scoop 集成踩坑记录 | 青空之蓝 「一行代码」优雅管理 Windows 软件 | 青空之蓝 [青空之蓝-2019]-年度总结 | 青空之蓝 为Vue添加简单的Store | 青空之蓝 为React添加简单的Store | 青空之蓝 为Vuex添加同步Action | 青空之蓝 浅谈跳表 | 青空之蓝 浅谈数据库索引 | 青空之蓝 MySQL事务隔离 | 青空之蓝 算法复杂度分析(1) | 青空之蓝 一年来的经验总结 | 青空之蓝 Acrylic - VSCode Extension | 青空之蓝 ace编辑器设置惯性滚动 | 青空之蓝 Java二叉树实现 | 青空之蓝 Java图实现 | 青空之蓝 为apt方式安装的nginx重新编译增加WebDAV | 青空之蓝 XK-Editor - 一个支持富文本和Markdown的编辑器 | 青空之蓝 JS生成列表树 | 青空之蓝 Laravel生成目录树 | 青空之蓝 XK-Note - 集各种神奇功能的云笔记 | 青空之蓝 PHP GD生成验证码 | 青空之蓝 PHP GD图片处理[转换格式-水印-缩略图] | 青空之蓝 Origami - 简洁轻快的WordPress主题 | 青空之蓝 为WordPress启用WorkBox | 青空之蓝 [青空之蓝-2018]-年度总结 | 青空之蓝 VSCode Java手动导入jar和源码包 | 青空之蓝 Windows IP变化自动发送邮件 | 青空之蓝 C链表实现重制版 | 青空之蓝 C 结构体的定义和使用 | 青空之蓝 图的搜索(遍历) - BFS & DFS | 青空之蓝 Java链表实现 | 青空之蓝 C 快速排序 | 青空之蓝 C 插入排序 | 青空之蓝 C 归并排序 | 青空之蓝 C语言链表实现 | 青空之蓝 VSCode配置Java调试环境[Windows] | 青空之蓝 C 选择排序 | 青空之蓝 C 冒泡排序 | 青空之蓝 VSCode配置PHP调试环境[Windows] | 青空之蓝 VSCode配置C/C++ GDB调试环境[Windows] | 青空之蓝 WordPress友情链接模板 | 青空之蓝 Intel Optane 傲腾内存体验 | 青空之蓝 Mysql双机热备实战 | 青空之蓝 博客一年记录 | 青空之蓝 为WordPress启用Service Worker | 青空之蓝 Bing每日一图API | 青空之蓝 iframe延迟加载 | 青空之蓝 写在2018年高考前 | 青空之蓝 The Fox主题汉化分享 | 青空之蓝 [青空之蓝-2017]-崭新 | 青空之蓝 本博客评论规则 | 青空之蓝 世界,您好! | 青空之蓝
浅谈B+树 | 青空之蓝
Otstar Lin · 2019-09-28 · via 青空之蓝

前言

**B+树(B Plus Tree)**是 MySQL 数据库索引的底层数据结构,B+树也是一种平衡树和 AVL 树以及红黑树有着同样的性能,不用你说,我知道你肯定又个疑问,为什么数据库要使用 B+树作为数据库索引而不是其他平衡树呢?为什么需要使用 B+树呢?或许看完这篇文章你应该就懂了。

其他结构的问题

数据库索引作为数据库中的重要组成部分,同时也是数据库性能的重要指标,数据库是索引必须拥有较好的性能,这包括执行效率(时间)和内存消耗(空间),在执行效率方面,我们希望通过索引,查询数据的效率尽可能的高;在存储空间方面,我们希望索引不要消耗太多的内存空间。

在以上的需求下,支持快速增删改查的数据结构除了 B/B+树大概还有以下几种:

  • 哈希表(Hash Table)
  • 跳表(Skip List)
  • 二叉搜索树(Binary Search Tree)
  • 红黑树(Red-Black Tree)
  • 平衡二叉树(AVL Tree)

首先看下哈希表,哈希表拥有 O(1)的增删改查的性能,乍一看似乎是最适合作为数据库索引的数据结构。但是,数据库索引不止能等值索引还需要支持范围索引,而哈希表并不能提供范围索引的功能,所以哈希表不能胜任。

接着是跳表,跳表之前的文章介绍过了,这里就直接说它的理由吧,跳表的空间复杂度是 O(nlogn)相比其他平衡结构差,而数据库需要应对的是大量的数据,需要大量的内存和磁盘空间,所以一般不采用跳表作为数据库索引的数据结构。

二叉搜索树在极端条件下会退化成链表,造成数据库性能不稳定的情况,而其他平衡树拥有更稳定的性能,所以不会使用二叉搜索树。

AVL 树都是一种极为成熟的平衡树结构,维护 AVL 树的平衡是非常耗时的,AVL 树适合用于插入删除次数比较少,但查找多的情况。而数据库有可能进行频繁的插入删除操作,所以不适合。

红黑树似乎是和 B/B+树一样适合作为数据库索引的,但是为什么 MySQL 不使用红黑树而是采用 B+树呢?首先红黑树并不太适合范围查找,还有其他的就在下面说明吧。

B+树

B+树是什么样子的呢?

首先为了支持范围查找,二叉树需要进行一些小改造:把数据都移到叶节点中,上层树结构只存储下层的索引。思路类似于跳表,但是上层索引使用的是树结构而不是链表结构。

除了执行效率和内存消耗的考虑,数据库索引还需要考虑其他一些东西:在海量的数据中索引应该存在哪?有些同学可能会说内存啊,但是内存真的能存下海量的数据索引吗?假如我们要存储 10 亿个字段,每个索引 12B 则叶节点大概需要 11G,整个索引树内存占用不大于 20G。20G 对于一台服务器已经是不小的压力了,所以,为了节省内存,如果把树存储在硬盘中,那么每个节点的读取(或者访问),都对应一次磁盘 IO 操作。树的高度就等于每次查询数据时磁盘 IO 操作的次数。而磁盘 IO 操作又极为耗时,所以为了减少磁盘 IO 操作则二叉树需要进行改造,将层高减少,即使用 N 叉树。

这样的结构就可以减少对磁盘 IO 的操作次数,同时又保留了高效的增删改查效率,而这种结构就是 B+树,数据由叶节点的指向,索引中在保留 key,节省内存。

这时有人就会问这个 N 要设置为多少为才是最好的?我们知道磁盘是按一定大小读取数据块的,这个大小是一个固定值,通常是 4KB,装系统中常说的 4K 对齐其实就是设置数据块的大小,为了防止读取一个 B+树节点的时候多次操作磁盘,同时最大化的利用每个数据块,B+树的每个节点应尽量充满整个数据块,通过计算就可以得出 N 的大小。

B+树是如何维持平衡的呢?

说了这么多,那 B+树作为一种平衡结构肯定有一种方式来维持平衡,在跳表中是随机高度,在平衡树中一般是采用左右旋的方式维持平衡,那么 B+树又是如何呢?

当数据量庞大的时候势必会造成某个节点的大小超过数据块的大小,如何很好的解决这种问题?没错就是分裂,将一个节点分成两份,这样每一份就都小于数据块的大小了,就能保证每次读取一个节点只需要一次磁盘操作了。

那分裂又是如何进行的呢?我们知道叶节点才是存储数据的节点,其他上层节点只存储了 key,但叶节点过大的时候节点进行分裂,分裂后数据的位置就不同了,所以还需要更新上层索引,当上层索引过大的时候就需要同叶节点一样分裂,直到分裂到根节点。

删除的时候就和分裂相反,当某个数据删除后节点中的数据数量少于某个特定的阈值的时候(通常是 N/2)就需要与兄弟节点进行合并,合并后同样需要更新上层索引,若合并后节点过大的时候就应该同插入一样进行分裂,直到两个节点的大小处于合理的范围之中。

总算更完这篇文章了,溜了溜了。插图看看吧,有空再画 (逃

浅谈B+树

https://blog.ixk.me/post/talking-about-bplus-tree
  • 许可协议

    BY-NC-SA

  • 本文作者

    Otstar Lin

  • 发布于

    2019/09/28

转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!

为Vuex添加同步Action浅谈跳表