16

一段时间以来,我一直在努力学习编程。我研究过 Java 和 Python,我对它们的语法很满意。最近,我想利用我所学到的知识从头开始编写一个有形的软件。

我想实现一个数据库引擎,一种 NoSQL 数据库。我整理了一个小文档,在我的整个编码过程中都遵循了规范。但我只知道一堆关键词。我不知道从哪里开始。

有人可以帮助我了解如何收集这种工作所需的知识以及学习的顺序吗?我已经搜索过文档,但我觉得我最终会找到不相关/错误的内容,或者从错误的点开始,因为实现一个完整的数据库引擎(似乎)是一项非常复杂的任务。

我不想表达我更喜欢论文、白皮书和(电子)书籍而不是其他项目的代码,因为我问过一个问题,人们通常会以“阅读项目 - x”的形式得到回答源代码”。我没有达到舒适阅读和理解源代码的水平。

4

2 回答 2

19

首先,您可能会看到如何编写一个简单的数据库引擎的答案。虽然它专注于 SQL 引擎,但答案中仍然有很多好的材料。

否则,一个好的项目教程是实现 B-Tree 数据库类。示例代码是用 C++ 编写的,但对所做的事情和原因的描述可能是您无论如何都想看的。

此外,在 MSDN 上还有Designing and Implementing Structured Storage (Database Engine) 。那里有大量信息可以帮助您完成学习项目。

于 2012-11-01T14:29:11.930 回答
17

因为接受的答案只提供(良好的)其他资源的链接,所以我想我会分享我编写webdb的经验,这是一个用于浏览器的小型实验数据库。我还邀请您阅读源代码。它很小。您应该能够通读它并在几个小时内基本了解它在做什么。警告:我在这方面是一个 n00b,自从写了它之后,我学到了很多关于它的知识,并且发现我做错了一些事情。不过,它可以帮助您入门。

基础知识:BTree

我开始调整 AVL 树以满足我的需要。AVL 树是一种自平衡二叉搜索树。您将键K和相关数据(如果有)存储在一个节点中,然后将所有项目存储key < K子树中的节点中,并将所有项目存储key > K子树中。如果要支持非唯一键,可以使用数组来存储数据项。

这棵树将为您提供基础知识:创建更新删除以及一种通过键快速获取项目的方法,或者键 < x 或键在 x 和 y 之间的所有项目等。它可以作为我们表的索引.

架构

作为下一步,我编写了让客户端代码定义模式的代码。诸如此类的方法createTable()。模式通常与 SQL 相关联,但即使是非 SQL 类型也有模式;他们通常要求您标记 ID 字段和您要搜索的任何其他字段。您可以使您的架构随心所欲,但您通常希望至少对哪些列用作主键以及哪些字段将被频繁搜索并需要索引进行建模。

创建数据结构来存储表

我决定使用我在第一步中创建的树来存储我的项目。这些是简单的 JS 对象。在定义了哪个字段包含 PK 之后,我可以简单地将项目插入到树中,使用该字段的值作为键。这使我可以按 ID(范围)快速查找。

接下来,我为需要索引的每一列添加了另一棵树。在这些树中,我没有存储完整的记录,而只存储了密钥。因此,要按姓氏获取客户,我将首先使用姓氏索引来获取 ID,然后使用主键索引来获取实际记录。我不只是存储(引用)实际对象的原因是因为它使集合操作更简单一些(见下一步)

查询

现在我们有了一个包含 PK 和搜索字段索引的表,我们可以实现查询。我没有把它走得太远,因为它很快就会变得复杂,但是你可以通过一些基础知识来获得一些不错的功能。WebDB 不实现连接;所有查询仅对单个表进行操作。但是一旦你理解了这一点,你就会看到一条非常清晰(虽然漫长而曲折)的路径来进行连接和其他复杂的事情。

在 WebDB 中,要让所有客户使用firstName = 'John'city = 'New York'(假设这是两个搜索字段),您可以编写如下内容:

var webDb = ...
var johnsFromNY = webDb.customers.get({
  firstName: 'John',
  city: 'New York'
})

为了解决这个问题,我们首先进行两次查找:我们获取名为“John”的所有客户 ID 的集合X ,以及来自纽约的所有客户 ID的集合Y。然后,我们对这两个集合执行交集,以获取所有来自纽约的名为“John” AND的客户的 ID。然后,我们遍历我们的一组结果 ID,获取每个 ID 的实际记录并将其添加到结果数组中。

使用联合和交集等集合运算符,我们可以执行ANDOR搜索。我只实现了AND

进行联接(我认为)涉及在内存中创建临时表,然后在查询运行时使用联接结果填充它们,然后将查询条件应用于临时表。我从来没有到过那里。接下来我尝试了一些同步逻辑,但这太雄心勃勃了,从那里开始走下坡路:)

于 2017-02-02T16:07:33.673 回答