1

我想暂时设计我自己的用于教育目的的数据库引擎。设计二进制文件格式并不难,也不是问题,我过去做过,但是在设计数据库文件格式时,我遇到了一个非常重要的问题:

如何处理项目的删除?

到目前为止,我已经想到了以下两个选项:

  • 每个项目都有一个“已删除”位,删除时设置为 1。
    • 亲:比较快。
    • 缺点:潜在的敏感数据将保留在文件中。
  • 0x00删除整个项目。
    • 亲:潜在的敏感数据将从文件中删除。
    • 缺点:相对较慢。
  • 重新创建整个数据库。
    • 优点:没有空块,这使得后续问题无效。
    • 缺点:覆盖整个 4 GB 数据库文件是一个非常好的主意,因为用户更正了一个错字。我会尽快把这个方法卖给 Twitter!

现在假设您的数据库中已经有一些空块(已删除的项目)。后续问题是如何处理插入新项?

  • 将项目附加到文件的末尾。
    • 亲:最快的可能。
    • 缺点:文件会变得很大,因为所有的空块仍然存在,因为删除的项目实际上并没有被删除。
  • 搜索与您要插入的块大小完全相同的空块。
    • 临:可能会摆脱一些障碍。
    • 缺点:您最终可能会在每次插入时扫描整个文件,却发现它不太可能遇到完美匹配的空块。
  • 找到第一个等于或大于您要插入的项目的空块。
    • 亲:你可能不会扫描整个文件,因为你会在中途发现一个空块;这将使文件大小保持相对较小。
    • 0x00缺点:在插入到比实际更大的空块中的项目末尾仍然会有很多剩余字节。

现在,我认为第一个删除方法和最后一个插入方法可能是“最好”的组合,但它们仍然会有自己的小问题。或者,第一种插入方法预定的完整数据库重新创建。(在处理非常大的数据库时可能不是一个好主意。此外,该方法中的每个小更新都会将整个项目克隆到文件末尾,从而以可能疯狂的速度加速文件增长。)

除非有一种以文件系统批准的方式从文件中间删除/插入块的方法,否则最好的方法是什么?更重要的是,目前生产中使用的数据库通常如何处理这个问题?

4

3 回答 3

2

您命名的引擎非常不同...而且您的引擎似乎与它们没有太多共同点...您的引擎听起来类似于良好的旧 dBase 格式...

对于删除,这个想法很好......用0x00可配置覆盖已删除项目的部分......

对于插入,您应该保留一个具有各自大小的空闲块列表...当您删除项目、增大文件以及缩小过滤器时,此列表会更新...这样您可以非常快速地确定如何处理插入...

于 2012-12-18T22:59:11.230 回答
1

为什么不从查看现有系统的工作原理开始呢?如果这是为了您自己的教育,从长远来看,这将使您受益更多。

对于初学者来说,看看久经考验的真正B-Tree / B+Tree 。然后看看其他一些,如分形树索引、SSTables、哈希表、合并表等。

首先了解“数据库”如何存储和索引数据。在 NoSQL 领域以及更传统的 RDBMS 领域中,都有很好的开源和文档示例。拆开现有的东西,理解它,修改它,改进它。

我一直走这条路,虽然不是为了教育目的。.NET 空间缺少任何基于磁盘的线程安全 B+Tree,所以我写了一个。你可以在我的博客http://csharptest.net/projects/bplustree/上阅读一些关于它的信息,或者去下载源代码并把它拆开:http ://code.google.com/p/csharptest-net/downloads/列表

于 2012-12-18T23:08:37.720 回答
1

有开源数据库你为什么不先看看它们。MySQL 源代码可以是一个好的开始。您可以下载源代码并进入它。

此外,您可以开始研究数据库使用的数据结构,然后查看持久性策略等。

于 2012-12-18T23:12:11.570 回答