RocksDb:每个键多个值(C++)

RocksDb: Multiple values per key (c++)

RocksDb:每个键有多个值 (c++)

我想做什么

我正在尝试调整我的简单区块链实现以定期将区块链保存到硬盘驱动器,因此我查看了不同的数据库解决方案信息。我决定使用 RocksDb,因为它易于使用,并且有很好的文档和示例。我通读了文档,但无法弄清楚如何使其适应我的用例。 我有一个class `

class Block {
public:
    string PrevHash;
    
private:
    blockheader header; // The header of the block 
    uint32_t index; // height of this block
    std::vector<tx_data> transactions; // All transactions in the block in a vector
    std::string hash; // The hash of the block
    uint64_t timestamp; // The timestamp this block was created by the node 
    std::string data; // Extra data that can be appended to blocks (for example text or a smart contract)
                      // - The larger this feild the higher the fee and the max size is defined in config.h
};

其中包含一些变量和一个结构向量 tx_data。我想将此数据加载到 rocksdb 数据库中。

我试过的

在 google 未能 return 使用一个密钥对存储多个值的任何结果后,我决定我必须在开始时将每个块数据包含在 0xa1 中,然后在结束时将 0x2a

*0x2a*
header
index
txns
hash
timestamp
data
*0x2a*

但决定肯定有更简单的方法。我试着查看 turtlecoin 使用的代码,这是一种使用 rocksdb 作为其数据库的货币,但那里的代码几乎无法辨认,我听说过序列化,但似乎没有关于它的信息。

也许我误解了数据库的使用?

您需要对其进行序列化。序列化是获取一组结构化数据并将其变成一个字符串、数字或字节向量的过程,然后可以在稍后将其反序列化回该结构。一种方法是获取块的哈希并将其用作数据库中的键,然后创建一个不包含哈希的新结构。然后编写一个函数,它接受一个 Block 结构和一个路径并构造一个 BlockNoHash 结构并保存它。然后另一个函数从哈希中读取一个块并吐出一个块结构。基本上你可以用一个永远不会出现在数据中的字符来分割每个字段(例如`或|),但这意味着如果一个数据被破坏那么你就无法获得任何其他数据

这里有两个相关的问题。

一个是:如何在像 RocksDB 这样的 key-value 存储中存储复杂数据——不仅仅是简单的整数或字符串。正如 Leo 所说,您需要将它们序列化。

与其编写自己的代码,通常更简单的方法是使用 Protobuf 或 Thrift 之类的框架来生成代码以在 in-memory 结构和适合存储的平面字节表示之间进行转换在数据库中(或通过网络发送。)

一个相关的问题,来自标题:如何为每个键存储多个值?

主要有两个选项:

  • 使用复合键来区分各种值。通过遍历键前缀,您可以找到一组相关键中的所有值。如果值变得非常大或者您想独立查找和更新它们,这会更好。

  • 或者,使单个键的值实际上成为包含多个内部值的复合 object。如果您总是想在一次操作中获取所有 sub-values,这是最简单的。