浅谈数据库内核原理(一)存储引擎篇

409 阅读6分钟

本文正在参加「技术专题19期 漫谈数据库技术」活动

参考书籍

《Database Internals:A Deep dive into How Distributed Data Systems Work》

前言

笔者自己也还是学生,对数据库没有太多实际的经验。截至目前,理论方面,上过《数据库系统概论》的课程,了解了传统关系型数据库的一些概念(关系代数、范式等);实践方面,只用过MySQL和华为的openGauss,在小黑窗下写过SQL语句。然而实际创建项目时,还是以使用可视化工具如Navicat进行点点点操作居多。但时间长了未免也感到厌倦。

我深知自己此前所了解到的关于数据库的内容就连皮毛都算不上,所以决定利用课余时间,查阅相关的书籍等,以对数据库机制有更深入的了解。

也许将来在工作中没有机会让我直接用到这些知识,但是探索的过程是很美妙的,不是吗? 我也认为这正是技术人所追求的价值与意义所在。

存储引擎

内存数据库与磁盘数据库的对比

这个分类是按数据的存储介质划定的。

内存数据库的数据 主要 存储在内存上,但也会在磁盘上有数据备份,以此保证数据恢复和日志记录;磁盘数据库则相反,它大部分数据都在磁盘上,内存只是用来临时存储或者作为缓存。

这两种数据库各有一个它们的存储介质所带来的特性:内存数据库上的数据无法被持久化存储;磁盘数据库的可以。

听上去磁盘数据库似乎最好,那为什么还会有内存数据库,并且实际上它的发展势头正旺呢?

正所谓存在即合理。世上没有任何一样事物能完美满足要求,因此总有另一种作为补充。这两类数据库互有优点,互为补充。

内存数据库的特点如下:

  • 从计算机组成原理我们了解到有个金字塔模型,内存在塔高层,磁盘在底层。内存访问比磁盘访问快了几个优先级。“快”是内存数据库的优势之一。
  • 相较于磁盘而言,内存更接近于顶层。基于内存的编程比基于磁盘的编程要简单得多。我们不需要手动管理数据引用、序列化格式、释放空间和碎片。 为什么要有操作系统这一抽象在硬件之上的底层软件、以及再之上的应用层软件也是类似的道理。底层最直接、最高效,但不是人人都有能力直接操作它。我们需要更抽象、更趁手、更符合人类思维方式的工具。而那些抽象它的开销在带来的好处面前就显得微不足道了。
  • 内存数据库在 数据结构 方面的选择性更大,且可以实现一些磁盘数据库无法实现的优化。

内存数据库相当于一个具有巨大页缓存的磁盘数据库吗?

答案是否定的。事实是:即使将磁盘数据库中的页缓存在内存里,序列化格式和数据布局也会产生额外开销,不会达到与内存数据库相同的优化程度。

行存储与列存储的数据库的对比

行存储是像我这样的初学者对数据库的第一印象。数据以表格的形式存在。一行存储一个对象的数据,每一列代表该对象的属性。

列存储则相反,从用户的视角看来,每一行开头第一个词是属性,之后一连串都是同一类型的数据。

列式存储如何定位重复的数据?

某些列式存储会使用offset(偏移量),将重复的数据映射回相关值。

在系统层面上两者有何不同?

我认为这类似于

for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
    }
}

for(int j=0;j<n;j++){
    for(int i=0;i<n;i++){
    }
}

在CPU上的影响。

据说,列式数据库中,一次从同一列中读取多个值会显著提高缓存利用率和计算效率。

且列式数据库在应用压缩算法上也会更有优势一些。

用户应该如何选择使用行式数据库还是列式数据库?

像我现在初学阶段接触到的xx管理系统这样主要是单条记录查询、且用到几乎所有属性的(即扫描范围很大的),用行式数据库就足够了;如果仅是要对 个别列 上的数据进行 聚合分析 、或者要跨越多行,可以考虑列式布局。

总之,没有优劣之分,要看应用场景更适合哪一个。

列式存储与宽列式存储的区分

实际上,column和wide column是截然不同的两种东西。

wide column的典型应用是Google的BigTable(在云计算这门课上了解过)、还有一个大数据领域用得比较多的数据库HBase。

我认为wide column的逻辑结构有点类似于json格式。

它有“族”的概念,不同列族分开存储,同一列族内属同一键的数据被存储到一起。

这篇文章对这个问题有很详细的解释,值得参考:

Bigtable数据模型和架构

与存储引擎相关的一些其他值得讨论的问题

数据库系统与文件系统的区别是什么?我们为什么需要数据库系统?

数据库系统区别于普通文件系统的点在于:它使用了特定的文件组织形式。

这样做有几大优点:

  • 文件以最小化单个存储数据记录开销的方式进行存储,提高了存储效率。
  • 用尽可能少的步骤定位记录,提高了访问效率
  • 更新记录更便捷,减少了访问磁盘的次数。

有关删除的问题

之前在云计算课上,老师也提到过,许多现代的数据库系统并不是直接删除记录(因为删除的开销是很大的,如果是顺序存储,得将后面的数据挨个往前移等等);而是对被删除数据做了一个标记(deletion marker/tombstone),待垃圾回收时这部分空间会被回收,页会被刷新,被删除的记录被丢弃,还在的纪录会被写入新位置。

数据库存储引擎的三大特性

  • (是否使用)缓冲
  • (是否具有)不可变性 云计算课上老师还提到过,以个人用户租用的轻量应用服务器为例,系统往往是支持不断添加新的数据,如果有重复的数据,则以最新添加的为准(时间戳最新的那个)。这种称为“只可追加的”,属于不可变结构。
  • 有序性 数据记录是否按键顺序存储在磁盘上的页中