在这篇文章中,我将会讲解一些数据库存储的内部机制,数据库是如何进行优化操作来提供惊人速度及其优势和缺点。

 当我们谈起数据库内部存储结构时,人们都会想到B树或者B+树,但是我们在这里并不会谈论这些数据结构的原理,我们会展示这些数据结构为什么适合作为数据库存储的内部结构以及使用这些数据结构的目的。

 传统的关系型数据将数据以B树的形式存储在磁盘上,它们也会在RAM上使用B树维护这些数据的索引,来保证更快的访问速度。插入的行存储在B树的叶子节点上,所有的中间节点用来存储用于导航查询语句的原数据。

因此,当有数以百万计的数据被插入到数据库中时,索引和数据存储会变得十分大。因此,为了快速的访问,需要从磁盘中加载所有数据到内存,但是RAM一般没有这么大的空间来存储所有的数据。因此,数据库必须从磁盘中读取部分数据。这种加载数据的场

景如下图所示:

 磁盘I/O花费的时间很长,是影响数据库性能的主要原因之一。B树是支持随机读写,in-place 替换,十分紧凑并且自平衡的数据结构,但是受磁盘I/O速度的限制。随机读意味着当访问磁盘数据时,磁头必须移动到柱面上的指定位置,因此会消耗大量时间。

 B树被设计为使用block的形式存储数据,因为操作系统读取读取一个block的数据要比读取单独字节数据要快的多。MySQL的InnoDB存储引擎的block大小为16KB。这意味着每次你读取或者写入数据时,大小为16KB的block数据会被从磁盘加载到RAM中,它会被

写入新的数据,并且再次写回到磁盘上。假设数据库表的每一行数据为128字节(实际大小会变化),一个block(叶子节点)为16KB,存储了(16 * 1024) / 128 = 128行数据。

B树的高度一般小于10,但是每一层的节点数量却很多,由此可以管理数以万计的数据。基于上述特性,B树适合作为数据内部存储结构。

 因此,在B树上进行读操作是相对来说比较快速的,因为该操作只需要遍历一些节点并且进行较少次数的磁盘I/O请求。而且,范围查询因为可以将数据以block的形式进行获取和操作而速度更快。你可以进行下列操作来让基于B-Tree的数据库性能更好:

减少索引节点数量:这是提升关系型数据库性能的常用策略。索引越多,插入和更新操作需要管理的索引数量也越多。当数据库数据运行时间越来越久时,就需要删除一些老旧或者无用的索引,并且谨慎地添加新的索引。但是你也要注意,索引越少意味着查询

性能越差,你需要在查询性能和插入更新性能之间进行取舍(译者注:可以考虑数据库的读写比率)。

顺序插入:如果你能以主键大小为基础进行大量数据的顺序插入,那么插入数据的速度会十分的快。因为在插入过程中,插入行所属的block已经在内存中,所以数据库可以直接将行插入到内存的数据结构中,然后通过一次磁盘I/O提交到数磁盘中。当然,这些都

取决于数据库的具体实现,但是我认为现代的数据库一般都会进行类似的优化。

 但是B树并不是适合所有情景的最优存储结构。对B树结构的写操作性能很差,比随机读还要差,因为数据库必须从磁盘中加载数据对应的页,然后修改它并冲洗新写入到磁盘中。随机写入时平均有100字节每秒写入速度,这个限制是由于磁盘的基本工作原理。

事实上,简单依赖于缓存的使用,索引搜索和更多的内存可以处理更多的读操作,但是应付更多的写操作就比较麻烦。当你需要写入或更新大量的数据时,B树结构并不是最正确的选择。长久以来,传统数据库进行了大量的优化,比如说InnoDB尝试使用缓冲来

减少磁盘I/O操作。具体操作如下所示:

image.png

 数据库写操作可以通过提升磁盘的带宽来提升速度,但是目前关系型数据库都没有这样做。而且关系型数据库管理系统一般都是十分复杂的,因为他们使用锁,并发,ACID事务等操作,这使得写入操作更加复杂。

 当今信息时代,在比如消息、聊天、实时通讯和物联网等客户为中心的服务和大量无结构化数据的分布式系统中,每小时都会进行数百万计的写入操作。因此,这些系统是以写为主的系统,为了迎合这些系统的需要,数据库需要能够拥有快速插入数据的能力。典

型的数据库并不能很好的满足类似的场景,因为它们无法应付高可用性,尽可能的最终一致性,无格式数据的灵活性和低延迟等要求。

 LSM树(Log Structured Merge Tree)应运而生。LSM并不是一种类似于B树的数据结构,而是一个系统。在LSM系统中,并没有对数据的in-place替换;一旦数据被写入磁盘,它就再也不会被修改。显然,它是一种只能在末尾添加(append only)的写入系统。一些

日志结构的文件系统比如ext3/4也使用类似的原理。

因此,该系统就如同顺序的记录数据日志一般。基本上,LSM系统利用了顺序写的优势。传统的磁盘驱动的写操作最高可以达到100MB/s,现代的固态硬盘在顺序写时的速度则更快。事实上,固态硬盘驱动有一些内置的并行机制来让它可以同时写入16到32MB的

数据。LSM树和固态硬盘的特性十分匹配。顺序写要比随机写快很多。

 为了正确地理解上述场景,让我们简单的看一下Facebook的Cassandra数据库是如何使用LSM原则的。

LSM系统示意图

 Cassandra或者任何LSM系统都会维护一个或者多个用来在写入磁盘前存储数据的内存数据结构(如上图中的memtable),比如说子平衡树(AVL)、红黑树、B树或者跳表。该内存数据结构维护一个排序的数据集。

不同的LSM实现互使用不同的数据结构来适应不同的需求,并不存在标准的LSM实现。当内存中存储的数据超过配置的阈值时,内存中存储的数据就会被放置在将会被写入磁盘的队列中。为了flush数据,Cassandra顺序地写入排序的数据到磁盘中。

磁盘维护一个叫做“SSTable”(Sorted Strings Table)的数据结构,该数据就是写入文件数据的有序的快照,SSTable是不可变的。LSM系统可以管理磁盘上的多个文件。

 因此,如果数据在内存中没有被发现,Cassandra需要扫描所有磁盘上的SSTables来搜索该数据。因此,Cassandra的读操作相对来说要比写操作慢,但是这里有一些可以处理的方法。Cassandra或者其他LSM系统会在后台运行压缩程序来减少SSTable的数量。

压缩程序对SSTable进行归并排序,在新的SSTable找那个插入新的排序数据并且删除老的SSTables。但是使用压缩程序有时候无法应付数据库中数以百万计的更新操作。

因此,一些概率数据结构(probabilistic data structures)比如Bloom filters被应用来快速判断是否一些数据存在于SSTable。Bloom filters十分适合对内存中的数据进行判断,因为它需要进行大量的随机查询来进行数据是否存在的概率性判断。Bloom filters算法可以

极大地减少遍历查询SSTables的花费。因此,LSM系统解决了在大数据中写操作需要花费大量时间的问题。

LSM系统也有Read amplification的问题-会读取出比它实际需要更多的数据。因此,还有介于B Tree和LSM Tree之间的解决方法来给出我们最优(不一定准确)的读写效率吗?

 Fractal Tree Index是基于B-Tree的数据结构。依据开发人员给出的benchmark,该数据结构有比B-Tree更优良的性能。Fractal tree支持在非叶节点上的信息缓存。MySQL的高性能存储引擎Tokudb就使用了Fractal tree。

Fractal Tree Index示意图

 如上图所示,在Fractal Tree中,你进行的添加列,删除列,插入,更新等任何操作都会被当做操作消息存储在非叶节点上。由于操作只是被简单地存储在缓存或者任何次级索引缓存(secondary index buffer)中,所以,所有的操作都会被迅速执行结束。

当某一个节点的缓存满了之后,这些操作消息会依次从根节点,经过非叶节点,向叶节点进行传递。叶节点仍然存储着真实数据。当进行读时,读操作会考虑查询路径节点上的所有操作消息来获取真实的数据状态。但是由于tokudb会尽力将所有非叶节点缓存在

内存中,所以这一过程也很快。

 tokubd中的block最大可以达到4MB,而不是InnoDB中的16KB。这样的大小可以允许一次I/O操作时加载或写回更多的数据,这也有助于一次压缩更多数据来减少磁盘上数据的存储大小。

因此,tokudb强调借助更大的block大小能够实现更好的数据压缩和更少的磁盘I/O。tokudb宣称它们的存储引擎比InnoDB更快,提供比InnoDB更快的读写吞吐,并且tokudb也宣称自己有更少的碎片(fragmentation)问题,它也支持多集群索引等。下图是benchmark的

相关统计图:

benchmark统计图

 只有你系统中的benchmark可以帮助你判断正确的数据点和需求解决方案。但是MySQL的存储引擎会持续地不断改进和支持新出现的需求。LSM树是为了高写入场景的系统,然而B树是为了传统的场景应用。Fractal树的索引改进了B树索引存在的一些缺陷。因

此,未来会不断地出现技术上的革新,包括数据库存储技术,硬件,磁盘驱动和操作系统,让我们拭目以待。

参考

  • 原文链接:https://medium.com/@kousiknath/data-structures-database-storage-internals-1f5ed3619d43

  • Cassandra:http://cassandra.apache.org/

  • SSTable and Log Structured Storage:https://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/

  • Fractal_tree_index:https://en.wikipedia.org/wiki/Fractal_tree_index

数据库内部存储结构探索相关推荐

  1. 题10 能给出数据库物理存储结构和物理存取方法的是什么?

    考查对数据库系统的认识 问:     能给出数据库物理存储结构和物理存取方法的是什么?     a.内模式     b.外模式     c.概念模式     d.逻辑模式      解析:     求 ...

  2. PyTorch 笔记(11)— Tensor内部存储结构(头信息区 Tensor,存储区 Storage)

    1. Tensor 内部存储结构 tensor 数据结构如下图所示,tensor 分为头信息区(Tensor)和存储区 (Storage),信息区主要保存着 Tensor 的形状(size).步长(s ...

  3. 数据库杂谈(七)——数据库的存储结构

    文章目录 7 数据库的存储结构 7.1 数据库访问管理-文件组织 7.2 数据库访问管理--索引技术 7 数据库的存储结构 让我们重新温习第六讲的所学知识. 这个图实际上我们要关注的是蓝色箭头指向的那 ...

  4. oracle实验报告2:: Oracle数据库物理存储结构管理(含实验小结)

    目录 实验目的 实验设备及器材 实验内容 实验步骤 实验过程 实验小结 实验目的 1.熟悉Oracle数据库物理存储结构: 2.掌握Oracle数据库数据文件的管理: 3.掌握Oracle数据库控制文 ...

  5. oracle的逻辑存储结构中由大到小的顺序,16.2 数据库逻辑存储结构

    16.2  数据库逻辑存储结构 数据库的物理存储结构对应一系列的物理文件,这部分内容主要描述的是数据存储的实际位置,不过数据如何存储,以什么结构存储到数据文件中,则取决于数据库的逻辑存储结构. 不会有 ...

  6. 赵强老师:Oracle数据库系列课程(12)管理数据库的存储结构与数据的并发-赵强老师-专题视频课程...

    赵强老师:Oracle数据库系列课程(12)管理数据库的存储结构与数据的并发-82人已学习 课程收益     从零开始学习Oracle数据库,让学员读整个Oracle数据库有个全面清除的认识和学习. ...

  7. sql2008表结构查看_【赵强老师】Oracle数据库的存储结构

    Oracle的存储结构分为:物理存储结构和逻辑存储结构. 一.物理存储结构:指硬盘上存在的文件 数据文件(data file) 一个数据库可以由多个数据文件组成的,数据文件是真正存放数据库数据的.一个 ...

  8. oracle临时表经常被锁_【赵强老师】Oracle数据库的存储结构

    Oracle的存储结构分为:物理存储结构和逻辑存储结构. 一.物理存储结构:指硬盘上存在的文件 数据文件(data file) 一个数据库可以由多个数据文件组成的,数据文件是真正存放数据库数据的.一个 ...

  9. 时序数据库的存储结构

    按series存储. 哈希取余 倒排索引:方便查询多条series. 符号表:存储将label排序,然后按序号索引获取,降低了存储开销,并且可以进行正则匹配. 正则匹配 block合并,主要是合并索引 ...

最新文章

  1. C语言文件最后一行重复储存,求大佬看看,我这个程序为什么保存进文件只有最后一行...
  2. 冒号课堂§2.4:并发范式
  3. linux 定位 踩内存_运维必备的问题定位工具及案例分析
  4. Spring Boot配置文件放在jar外部
  5. ArrayList,Vector, LinkedList的存储性能和特性?
  6. iif能用到mysql中吗_请问ORACLE中IIF如何用
  7. 机器学习Tensorflow基本操作:线程队列图像
  8. Android App Architecture使用详解
  9. UOS系统JAVA应用在任务栏显示类名的问题跟踪调用
  10. Flink源码篇,作业提交流程、作业调度流程、作业内部转换流程图
  11. 破局数据库“卡脖子”:专精特新“小巨人”偶数科技迎风成长
  12. 简历中对技术的描述词汇:了解,熟悉,掌握,熟练,精通
  13. 星星之火-30:什么是WCDMA的伪随机码与扰码?
  14. 罗杨老师带你了解谷歌编程之夏(GSoC)活动全流程
  15. 【人工智能】1024 程序员节最想要的大礼包!
  16. 什么是美国次贷危机,看后你就明白了
  17. 云托管,边缘物理计算托管物理计算,你所需要了解的……
  18. uniapp 权限树模块- ly-tree组件
  19. 关于CSS粘性定位——sticky
  20. 苹果系统地图定位服务器,苹果手机能1秒定位对象在哪?你知道吗?

热门文章

  1. 这些东西,你知道吗?是否忘记了
  2. Android UI学习 - GridView和ImageView的使用
  3. web_安全_文件上传漏洞
  4. [LeetCode] Remove Duplicates from Sorted List - 链表问题
  5. OpenGL之矩阵堆栈绘制立体图元
  6. 用几十行代码实现python中英文分词
  7. Python 奇技淫巧
  8. 排序算法 —— 选择排序
  9. 《C champion》 为什么要学习C语言
  10. 【Linux】一步一步学Linux——let命令(223)