161

我有兴趣了解数据库引擎的工作原理(即它的内部结构)。我知道 CS 中教授的大多数基本数据结构(树、哈希表、列表等),并且对编译器理论有很好的理解(并且已经实现了一个非常简单的解释器),但我不明白该怎么做关于编写数据库引擎。我已经搜索了有关该主题的教程,但找不到任何教程,因此我希望其他人可以为我指明正确的方向。基本上,我想了解以下信息:

  • 数据如何在内部存储(即如何表示表等)
  • 引擎如何找到它需要的数据(例如运行 SELECT 查询)
  • 如何以快速高效的方式插入数据

以及可能与此相关的任何其他主题。它不必是磁盘数据库——即使是内存数据库也可以(如果它更容易的话),因为我只想了解它背后的原理。

非常感谢您的帮助。

4

9 回答 9

66

如果您擅长阅读代码,那么学习 SQLite 将教会您大量有关数据库设计的知识。它很小,所以更容易把你的头包起来。但它也写得很专业。

http://sqlite.org/

于 2009-06-27T05:56:25.083 回答
27

这个问题的答案是一个巨大的问题。期望一篇博士论文能得到 100% 的回答 ;) 但我们可以一一思考问题:

  • 如何在内部存储数据:你应该有一个包含数据库对象的数据文件和一个缓存机制来加载焦点数据和它周围的一些数据到 RAM 假设你有一个表,有一些数据,我们将创建一个数据格式将此表转换为二进制文件,方法是同意列定界符和行定界符的定义,并确保在您的数据本身中永远不会使用这种定界符模式。例如,如果您选择了 <*> 来分隔列,则应验证您放置在此表中的数据不包含此模式。您还可以通过指定行的大小和一些内部索引号来使用行标题和列标题来加快搜索速度,并在每列的开头设置此列的长度,如“Adam”、1、11.1、 "

  • 如何快速查找项目尝试使用散列和索引来指向基于不同标准存储和缓存的数据,以上面相同的示例为例,您可以对第一列的值进行排序并将其存储在指向按字母排序的项目的行 id 的单独对象中, 等等

  • 如何加快插入数据我从 Oracle 知道的是,他们在 RAM 和磁盘上的临时位置插入数据并定期进行内务处理,数据库引擎一直忙于优化其结构,但同时我们不想要在类似的电源故障的情况下丢失数据。因此,请尝试将数据保存在这个临时位置而不进行排序,附加您的原始存储,然后在系统空闲时使用您的索引并在完成后清除临时区域

祝你好运,伟大的项目。

于 2009-06-27T06:03:34.760 回答
14

有关于该主题的书籍,一个很好的起点是数据库系统: Garcia-Molina、Ullman 和 Widom的全书

于 2009-06-27T05:55:34.727 回答
12

之前提到过 SQLite,但我想补充一点。

我个人通过学习 SQlite 学到了很多东西。有趣的是,我没有去看源代码(虽然我只是看了一眼)。通过阅读技术资料并特别查看它生成的内部命令,我学到了很多东西。它内部有一个自己的基于堆栈的解释器,您可以通过使用解释来读取它在内部生成的 P 代码。因此,您可以看到各种构造如何转换为低级引擎(这非常简单——但这也是其稳定性和效率的秘诀)。

于 2009-06-27T09:02:06.553 回答
10

我建议关注 www.sqlite.org

它是最近的、小型的(源代码 1MB)、开源的(所以你可以自己弄清楚)......

已经写了一些关于它是如何实现的书籍:

http://www.sqlite.org/books.html

它可以在台式电脑和手机的各种操作系统上运行,因此实验很容易,学习它在现在和将来都会很有用。

它甚至在这里有一个不错的社区:https ://stackoverflow.com/questions/tagged/sqlite

于 2009-06-27T06:01:01.800 回答
10

好的,我找到了一个站点,其中包含一些有关 SQL 和实现的信息 - 链接到列出所有教程的页面有点困难,所以我将它们一一链接:

于 2009-06-30T07:13:34.367 回答
8

也许你可以向HSQLDB学习。我认为他们提供了小而简单的学习数据库。您可以查看代码,因为它是开源的。

于 2009-06-27T06:02:58.550 回答
4

如果你对 MySQL 感兴趣,我也会推荐这个wiki 页面,它提供了一些关于 MySQL 工作原理的信息。此外,您可能想看看Understanding MySQL Internals

您还可以考虑查看数据库引擎的非 SQL 接口。请看一下Apache CouchDB。它就是您所说的面向文档的数据库系统。

祝你好运!

于 2009-06-27T07:50:17.853 回答
3

我不确定它是否符合您的要求,但我已经SELECT, INSERT , UPDATE使用 perl 实现了一个简单的面向文件的数据库,支持 simple ()。
我所做的是将每个表作为一个文件存储在磁盘上,并以明确定义的模式存储条目,并使用内置的 linux 工具(如 awk 和 sed)来操作数据。为了提高效率,缓存了经常访问的数据。

于 2009-06-27T07:27:49.473 回答