1

我们有我们的内部 noSQL 数据库,它基本上将所有内容存储在一个紧凑的二进制文件中。现在,我需要一个类似于键值存储或 B+Tree 的数据结构。在我的情况下,问题是“价值”可以是不同的类型,并且大小非常不稳定,可能从 1Kb 到 1-2Gb。通常,键是字符串,值是数据流,可以是 int、string 或自定义类型的流。

我正在考虑实现 B+ 树,但这并不容易,因为 B+ 树需要“值”的类型相同,并且“值”的大小应该足够小,可以存储在相对较小的块中。可能有一个变体,但我没有找到关于如何实现 B+ 树的教程,其中包含显示如何存储在磁盘上的示例。我看到的大部分教程都只是内存中的 B+ 树。

然后我有了使用文件夹/文件名作为键的想法。然后该值可以是文件中的任何内容。然后值可以是任意大小,这就是我想要的。所以我的问题在这里,在极端情况下,

  • 不同日期的数据存储在单独的文件夹中
  • 我可以有 1M-50M 密钥(实际上是文件/文件夹)在磁盘上存储一天
  • 对文件的数据操作通常是“只读”的,白天是“附加到”的。历史数据永远不会被修改。

我已经看到我可以在现代操作系统上拥有约 40 亿个文件,因此我对这种在单台机器上存储约 2 年的方法感到满意。我只是担心这种实现键值存储的方式是否非常糟糕?为什么?处理文件系统时我会遇到什么问题?(例如,Windows 上的框架磁盘?)

所有都在 Windows/Linux 中用 C++ 实现。

4

3 回答 3

0

“不同日期的数据存储在不同的文件夹中” - 如果您想跨天搜索单个数据,这并不方便。

此外,当每个文件夹的文件数量超过文件系统限制时,您可能会遇到问题。磁盘上 40 亿个文件不是问题,单个文件夹中 50M 是问题。但是,当然,您不需要将所有内容都存储在同一个文件夹中。一个键可以分为文件夹部分和文件名部分。

如果您需要依赖 B-Tree 属性来查找一系列键,事情就会变得棘手。这意味着您需要一个订单,并且不能使用散列函数将密钥映射到文件夹/文件名对。在这种情况下,你有一个问题。最坏的情况是你的密钥只是连续的“1”到“999999999”,再加上一组随机的更大的密钥。这意味着您不能将最后 4 位数字用作文件名(文件夹太多)或最后 8 位数字(文件太多)。

于 2016-05-25T15:47:51.677 回答
0

你为什么担心价值的大小。您可以使用现有的数据库。值可以是以下格式的字符串“type|value_data”,其中“|” 是分隔符。

这里,value_data 可以是“实际值”或“包含值的文件路径”

  • type = LOCAL(在这种情况下 value_data 将是实际值,如果它可以适合 db)
  • type = REMOTE(在这种情况下 value_data 将是文件的路径)
于 2016-05-25T12:44:02.703 回答
0

我认为,如果您可以确保并满足您的要求,那应该还不错。我为嵌入式项目及其有限的数据集做了类似的事情。

需要考虑的事情

  1. 操作系统/文件系统应支持所需的文件夹长度(键)和文件名(如何选择)
  2. 它确实使磁盘碎片化,并且可能会延迟对巨大目录结构的磁盘访问。这可能会影响整个系统进程。
  3. 应用程序性能可能会降低,因为读/写操作取决于文件操作 - 如果需要,您可能可以在程序中添加缓存。
  4. 对于多线程应用程序不利,应注意文件锁定。
  5. 应注意安全。
于 2016-05-25T12:27:08.370 回答