【问题标题】:c++ best way to store arrays or vectors of objects on disk for a simple databasec++ 为简单数据库在磁盘上存储对象数组或向量的最佳方法
【发布时间】:2013-10-05 07:44:09
【问题描述】:

我一直在开发用于安排电视录制的 PVR 后端,我正在尝试找出保存包含所有相关信息的简单数据库的最佳方法。我整理了一个懒人的原型(如下所示),但我不想静态分配巨大的数组,然后简单地将这些对象的 ram 内容转储到磁盘进行存储。

鉴于以下懒惰/不良实践原型,我的最佳选择是什么?一个有经验的程序员会如何选择做这样的事情?如果我要在不使用 toString/fromString 函数的情况下完成这一切,我该怎么做?

struct Recording{
    Date date;
    int channel;
    int length; //length in hours, minutes, or seconds
    bool is_interlaced; //if true, denotes that the episode is interlaced
    bool done; //if true, denotes that the episode has been recorded
    bool record_successful; //Currently unused
};

struct TV_Episode{
    struct Recording recording;
    char title[128]; //Episode Title
    char season; //Season number
    char episode; //Episode number
};

struct TV_Show{
    char name[64]; //TV Show name
    char numepisodes; //The number of episodes in the array
    struct TV_Episode episodes[100]; //Array containing airings of a TV show
};

struct Movie{
    struct Recording recording;
    char title[128]; //Movie Title, optionally including the year in brackets
};

struct Recordings_DB{ /*
    * Obviously these types can be done away with using inheritance
    * and the Recordings_DB type can be done away with using a vector.
    * They are just here to illustrate the concept.
    */
    struct TV_Show shows[20];
    struct Movie movies[20];
};

【问题讨论】:

  • 考虑 XML 或 JSON 之类的东西,并学习对其进行序列化。优点是你有一个结构化的文件,但在你弄清楚东西时仍然可读。

标签: c++ storage


【解决方案1】:

我实际上在 PVR 机顶盒领域工作了 5 年以上,而在我的老公司,我们也面临着类似的选择。由于您的意图是将 PVR 记录存储在磁盘上,因此您可以采取以下一些方法 -

  1. 二进制协议:将 C 或 C++ POD 类型转储到二进制文件。这将需要在添加/删除字段时难以保持兼容性的自定义解析器。也不是人类可读的,所以调试会很痛苦。如果您出于速度或磁盘使用原因选择此路线,请至少使用 Google 的 protocol buffers 作为二进制协议。
  2. 序列化协议 使用 XML、JSON 等人类可读协议将数据序列化到磁盘或从磁盘序列化。易于调试,也易于向模式中添加/删除字段。有很多开源解析器可用,例如expat、libxml2、rapidjson、json-c 可以为您完成繁重的工作。
  3. 嵌入式数据库 如果你的系统需要支持排序、搜索、过滤等,我强烈推荐SQlite,一个适合嵌入式平台的轻量级数据库,带有原生C接口。此选项需要更多的前期开发工作,但随着系统的发展会更好地扩展。

【讨论】:

  • 感谢您的帮助。我很感激。我有一段时间没有编程了,所以我很生疏,而且我从来没有在高级别的东西上做过很多事情。您会推荐任何好的 C++ 初学者 SQL 教程吗? (我过去使用过 SQL,但使用的是 PHP,而不是 C/C++)
  • Definitive Guide To Sqlite 是一本深入了解 SQLite C 接口的知识和最佳编码实践的好书。我没有使用很多教程,但这个 online tutorial 看起来很有希望。
  • 感谢您提供信息并包含亚马逊链接,因为无论如何我通常都会从他们那里订购。我刚刚订购了两本关于 SQL 的书,我想我会在完成另外两本后订购这本。感谢您的帮助!
【解决方案2】:

如果你不想静态分配数组,那为什么不使用std::stringstd::vector呢?您可以获得正确大小的动态分配,并且您对最大大小没有限制。这是双赢。

也不要将char 用于整数值。这种一分钱一分货是不必要的。它只会回来咬你。还记得千年虫吗?信不信由你,现代计算机拥有大量内存和磁盘空间。在许多情况下,由于填充,您实际上并没有节省任何内存。

【讨论】:

  • 使用 char 更多是为了踢球和再次使用铸造。但是,我的意思是存储,就像存储在磁盘上一样。此外,char 数组更多,因此我可以编写一个方案,如果我真的想的话,我可以将整个内存空间转储到硬盘驱动器并让它在我寻找更好的选择时工作(因此这篇文章)
【解决方案3】:

这可能有点烦人,因为您要么需要编写自己的序列化代码(tostring/fromstring),要么采用一个库。如果您自己编写,请务必考虑将字段添加到其中一个结构但希望能够以旧格式读取的情况;提前计划对解决这个问题有很大帮助。

您可能会考虑的两个选择是 Google 的协议缓冲区库(您将定义协议缓冲区而不是结构,然后您可以序列化顶级 RecordingsDB)或 SQLite(您必须编写一些基本的 SQL 来填充字段,但您还可以获得索引和事务)。如果您的数据库永远不会超过几千条记录,我建议使用协议缓冲区,因为 SQL 不会给您带来太多好处。两者都是相当紧凑、简单的库,得到很好的支持。

【讨论】:

    猜你喜欢
    • 2011-03-23
    • 2016-08-27
    • 1970-01-01
    • 2012-03-26
    • 2021-11-27
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多