我正在寻找C ++中的嵌入式数据存储引擎。 RocksDB是键值存储。
我的数据非常相似。我的类型数量很少(大约20种),而且我存储了很多这些类型的实例(大约100万个实例)。
我认为数据的均匀性使RocksDB成为一个糟糕的选择。如果我分别序列化每个对象,那么肯定要复制架构元数据吗?肯定会导致性能下降吗?
所以我的问题是: RocksDB是存储同类对象的好选择吗?如果是,那么如何避免重复架构元数据的性能影响?
答案 0 :(得分:1)
据我了解,RocksDB实际上是一个KeyValue存储,而不是一个数据库。 这意味着您仅能存储二进制键和值数据。与普通数据库(例如MySQL,SQLite)不同,您不会获得可用于定义列/类型等的表。
因此,由您的程序来决定如何存储数据。
一种可能性是将数据存储为JSON值,在这种情况下,您要说要付出在值中存储“模式”(即JSON字段名称)的费用。
另一个选择可能是,您有一个名为 SCHEMA 的特殊键(例如),其中包含所有对象类型的AVRO模式。您的应用程序可以在启动时读取它,初始化读取器/写入器,然后知道如何处理RocksDB中存储的每个键值。
另一个选择可能是您在应用程序中对逻辑进行硬编码。您可以为此使用任何数量的库,包括AVRO(如上所述)或MsgPack及其变体。在这种情况下,如果您打算进行任何模式更改,则如果要使用该应用程序先前版本中的RocksDB数据,则需要格外小心。因此,也许在数据库中存储版本号或其他内容。
答案 1 :(得分:1)
与例如sqlite不同,RocksDB中没有架构元数据,因为没有架构:它将二进制密钥映射为二进制值。 RocksDB没有内置的序列化。如果要存储对象,则必须自行序列化它们,并使用例如键,键前缀或列族(〜DB表亮)来区分类型。
通常,您将使用RocksDB构建某种自定义数据库。有人在其顶部建立了Protobuf对象的缓存(ProfaneDB)。通常,我会说它太底层了,但是如果您不需要结构化数据和查询,它将很好地工作,非常快并且通常令人愉快(它们的代码可读性强,有时是最好的文档,因为您将处理数据库内部问题。
我以前在小型玩具应用程序中使用过varint键前缀,最多只有127种类型的字节开销,但是列系列对于prod应用程序可能更可取。它们还具有恒定的开销,并且可以单独进行调整,添加,删除和管理。我不会放弃您从它们那里获得的其他功能。如果您选择RocksDB,那也大致代表了您所处问题的级别。