如何编写一个简单的数据库引擎


143

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

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

以及与此相关的任何其他主题。它不必是磁盘上的数据库,即使是内存数据库也很好(如果更简单的话),因为我只是想学习它的原理。

非常感谢您的帮助。

Answers:


55

如果您擅长阅读代码,那么学习SQLite将会教会您有关数据库设计的全部知识。它很小,所以更容易缠头。但是它也是专业写的。

http://sqlite.org/


2
sqlite下载shell.c的LOC.c => 3135,sqlite3.c => 136332,sqlite3ext.h => 447,sqlite3.h => 7097,总计=> 147011
Khaja Minhajuddin

1
这可能与使用花括号语言制作功能全面的数据库引擎差不多。SQLite也可以在C#中使用。
罗伯特·哈维


4
我建议阅读SQLite 2.5.0的代码:github.com/davideuler/SQLite-2.5.0-for-code-reading,它是SQLite的早期版本,可以在现代GCC上编译和运行(我已经测试过它在MacOS 10.13和Debian 8上)
David Euler

1
cstack.github.io/db_tutorial是一个很好的起点。
Ashish Negi '18

25

这个问题的答案是巨大的。希望PHD论文能回答100%;),但是我们可以一一思考这些问题:

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

  • 如何快速查找项目尝试使用哈希和索引来指向基于不同条件的存储和缓存数据(采用与上述相同的示例),您可以对第一列的值进行排序并将其存储在指向按字母顺序排序的项目的行ID的单独对象中, 等等

  • 我从Oracle那里知道如何加快插入数据的速度,即它们将数据插入RAM和磁盘上的临时位置并定期进行内务处理,数据库引擎一直在忙于优化其结构,但与此同时我们不这样做想要在断电之类的情况下丢失数据。因此,请尝试不进行排序就将数据保留在此临时位置中,追加原始存储,然后在系统空闲时重新使用索引,并在完成后清除临时区域

祝你好运,伟大的项目。


11

之前提到过SQLite,但我想添加一些内容。

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




8

我建议重点关注www.sqlite.org

这是最近的小型(源代码为1MB)开放源代码(因此您可以自己弄清楚)...

有关如何实现它的书籍已经写成:

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

它可以在台式机和移动电话的各种操作系统上运行,因此实验很容易,并且现在和将来进行了解都将是有用的。

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


1
现在,3.10的字节大小几乎是7.0 mb的源代码。只有少数人可以一口气消化所有食物。尽管如此,也是一个不错的起点。
Laurie Stearn,2015年

1
确实。最近在SQLite的源代码中花了一些时间来查找SQLCipher中的错误,这绝对是一场噩梦。生活在6年前更简单了:-)
迈克尔·奥伯特

我想念聚会时只是一个简单的问题,我想从第一个版本开始会轻松得多(也许有用)?实际上,对于大型项目的所有认真代码阅读,我都应该这样做吗?
尼古拉斯·汉弗莱

7

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


3

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


1
您还有代码吗,您可以共享链接吗?
GK1

3

如果MySQL使您感兴趣,我也建议您访问这个Wiki页面,该页面已获得有关MySQL工作方式的一些信息。另外,您可能想看看了解MySQL内部知识

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

祝好运!


如果您想查看另一个数据库:sqlserverinternals.com,则有关SQl服务器内部的nbooks最受关注。
HLGEM 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.