按文件夹名称存储键值
Key-value store by foldername
我们有自己的内部noSQL数据库,它基本上将所有内容存储在一个紧凑的二进制文件中。现在,我需要一个类似键值存储或B+树的数据结构。问题是,在我的情况下,"值"可以是不同类型的,大小非常不稳定,可能从1Kb到1-2Gb。通常,键是字符串,值是数据流,可以是int、string或自定义类型的流。
我曾考虑实现一个B+树,但这并不容易,因为B+树需要"value"为相同类型,并且"value"的大小应该足够小,可以存储在相对较小的块中。可能有一个变体,但我没有找到如何实现B+树的教程,并提供了如何在磁盘上存储的示例。我看到的大部分教程都只在内存B+树中。
然后我有了使用文件夹/文件名作为密钥的想法。然后该值可以是文件中的任何内容。值可以是任意大小的,这正是我想要的。所以我的问题是,在极端情况下,
- 不同日期的数据存储在不同的文件夹中
- 我可以有1M-50M的密钥(实际上是文件/文件夹)在磁盘上存储一天
- 对文件的数据操作通常是"只读"的,并在白天"附加到"。历史数据永远不会被修改
我已经看到,在现代操作系统上我可以拥有大约40亿个文件,所以我对在一台机器上存储大约2YR的方法感到满意。我只是担心实现键值存储的方式是否非常糟糕?为什么?处理文件系统时会遇到什么问题?(例如,窗口上的带框磁盘?)
所有这些都是在Windows/Linux中用C++实现的。
我认为,如果您能够确保并满足您的需求,那应该还不错。我为一个嵌入式项目及其有限的数据集做过类似的事情。
需要考虑
- 操作系统/文件系统应支持所需的文件夹(密钥)和文件名长度(选择方式)
- 它确实会使磁盘碎片化,并且可能会延迟对巨大目录结构的磁盘访问。这可能会影响整个系统流程
- 应用程序性能可能会降低,因为读/写操作取决于文件操作——如果需要,您可能可以在程序中添加缓存
- 对多线程应用程序不好,应该注意文件锁定
- 应注意安全
为什么担心值的大小。您可以使用现有的数据库。值可以是以下格式的字符串"type|Value_data",其中"|"是分隔符。
这里,value_data可以是"实际值"或"包含值的文件路径">
- type=LOCAL(在这种情况下,value_data将是实际值,如果它可以适应数据库)
- type=REMOTE(在这种情况下,value_data将是文件的路径)
"不同日期的数据存储在不同的文件夹中"-如果您想跨天搜索单个数据,这并不方便。
此外,当每个文件夹的文件数超过文件系统限制时,您可能会遇到问题。一个磁盘上有40亿个文件不是问题,一个文件夹中有5000万个是问题。但当然,你不需要把所有东西都存储在同一个文件夹里。密钥可以分为文件夹部分和文件名部分。
如果您需要依赖B-Tree属性来查找键的范围,那么事情确实会变得棘手。这意味着您需要一个顺序,并且不能使用哈希函数将密钥映射到文件夹/文件名对。在这种情况下,你就有问题了。最糟糕的情况是,您的密钥连续只有"1"到"999999999",加上一组更大的随机密钥。这意味着不能使用最后4位数字作为文件名(文件夹太多)或最后8位数字(文件太多)。
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何使用 std::variant 打印地图键/值?
- 当键值是 std 向量时,为什么使用 at in C++ 访问映射值如此缓慢?
- C++ 映射的键/值的用户自定义名称?
- 试图(稍微)概括C++模板.关联容器键:值反转
- 使用无序映射在STL中存储键值对
- 如何将 JSON 键值(我使用 cpp boost 解析)存储在相关数据结构中?
- 使用 k 个键值对为零的存储桶初始化 c++14 unordered_map
- 按文件夹名称存储键值
- 是否存在可以在iOS上运行的本地键值存储DB(与redis不同)
- 存储桶键值映射
- 如何在不使用任何DBMS的情况下将键值对数据存储在程序中
- 存储文件中的键值数据
- 如何调整无序STL容器以仅存储键值对的值
- 在文件中存储由分隔符分隔的大量整数的键值对的最有效方法
- 如何构建编译时键/值存储
- 在b树中存储一对键值
- 从字符串中获取键/值对并存储在map中
- 是否存在任何键值容器来存储它们的元素而不进行任何重新排序?
- c++中,通过使用for循环在map中存储键和值