【问题标题】:Which database should I use to store records, and how should I use it?我应该使用哪个数据库来存储记录,我应该如何使用它?
【发布时间】:2010-12-14 09:44:48
【问题描述】:

我正在开发一个可以存储大量记录的应用程序。这些记录将类似于(URL、日期、标题、来源、{可选数据...})

由于这是一个客户端应用程序,我不想使用数据库服务器,我只想将信息存储到文件中。

我希望这些文件可以从各种语言(至少是 python 和 C++)中读取,所以像 python 的泡菜这样的特定语言是不合适的。

我看到了两种可能性:sqlite 和 BerkeleyDB。由于我的用例显然不是关系型的,所以我很想使用 BerkeleyDB,但是我真的不知道应该如何使用它来存储我的记录,因为它只存储键/值对。

我的推理正确吗?如果是这样,我应该如何使用 BDB 来存储我的记录?你能把我链接到相关信息吗?还是我错过了更好的解决方案?

【问题讨论】:

  • 感谢大家提供的非常有帮助的答案!选择一个最好的真的很困难:-/

标签: c++ python database persistence


【解决方案1】:

我看到了两种可能性:sqlite 和伯克利数据库。因为我的用例是 显然没有关系,我很受诱惑 与 BerkeleyDB 一起去,但我不 真的知道我应该如何使用它 存储我的记录,因为它只存储 键/值对。

您所描述的正是关系的含义,即使您只需要一张表。 SQLite 可能会让这很容易做到。

编辑: 关系模型与表之间的关系没有任何关系。关系是其他集合的笛卡尔积的子集。例如,实数、实数和实数(是的,所有三个都相同)的笛卡尔积产生 3d 坐标空间,您可以使用公式在该空间上定义关系,例如 x*y = z。每个可能的坐标集(x0,y0,z0) 如果它们满足给定的公式,则它们要么在关系中,要么不在关系中。

关系数据库使用这个概念,但有一些额外的要求。首先,也是最重要的,关系的大小必须是有限的。上面给出的乘积关系不满足这个要求,因为满足公式的三元组有无穷多个。还有许多其他考虑因素与解决实际问题的真实计算机上的实用性或有用性有关。

思考问题的更好方法是考虑每种类型的持久性机制在哪些方面比另一种更有效。您已经认识到,当您有许多必须支持它们之间的关系(外键约束)的单独数据集(表)时,关系解决方案是有意义的,这几乎不可能通过键值存储来实施。关系的另一个真正优势是它可以通过使用适当的索引来实现丰富的即席查询。这是数据库层实际理解它所代表的数据的结果。

键值存储有其自身的优势。其中一个更重要的是键值存储扩展的方式。 memcachedcouchdbhadoop 都使用 key-value 存储是没有关系的,因为很容易将 key-value 查找分布在多个服务器上。另一个可以很好地存储键值的领域是当键或值是不透明的时,例如当存储的项目被加密时,只能被它的所有者读取。


为了强调这一点,即使您不需要多个表,关系数据库也能很好地工作,请考虑以下(非原创)

SELECT t1.actor1 
FROM workswith AS t1, 
     workswith AS t2, 
     workswith AS t3, 
     workswith AS t4, 
     workswith AS t5,
     workswith AS t6
WHERE t1.actor2 = t2.actor1 AND
      t2.actor2 = t3.actor1 AND
      t3.actor2 = t4.actor1 AND
      t4.actor2 = t5.actor1 AND
      t5.actor2 = t6.actor1 AND
      t6.actor2 = "Kevin Bacon";

其中,显然使用一个表:workswith 来计算每个演员的培根数为 6

【讨论】:

  • 您能详细说明一下吗?对我来说,只有当你有几个表之间存在关系时,关系才有意义......
【解决方案2】:

BerkeleyDB 很好,也可以看看 *DBM 的化身(例如 GDBM)。但最大的问题是:您需要搜索什么?您是否需要按该 URL、一系列 URL 或您列出的日期进行搜索?

也很可能将记录组作为简单文件保存在本地文件系统中,按日期或搜索词分组等。

回答“搜索”问题是最大的开始。

至于键/值的东西,您需要确保 KEY 本身在您的查找中得到了很好的定义。例如,如果您有时需要按日期查找,而其他人需要按标题查找,则需要维护一个“记录”行,然后可能需要 2 个或更多“索引”行来引用原始记录。您几乎可以对键/值存储中的任何内容进行建模。

【讨论】:

  • “您几乎可以对键/值存储中的任何内容进行建模。”你能推荐一些关于这个的东西吗?我可以看到这个模型非常通用,但是阅读一些示例会很有用。
  • 我可以看到我能找到什么,但底层数据库存储的传统基础实际上是某种机制中的键/值存储。堆表只是写入键/值的行,行作为值,键是生成的 ROWID 排序。此类表上的非复合索引将索引的值列为键,将 ROWID 列为值。当然它变得比这更复杂,但是没有另一个级别的间接性就无法解决在这里适用。如果我能找到几篇文章,我会发表评论。
【解决方案3】:

我个人还是会使用 sqlite。它一直对我有用(以及与我一起工作的其他人)。当您的应用程序增长时,您突然想要做一些更复杂的事情,您不必重写。

另一方面,我在 Python 开发人员列表中看到了有关 Berkely DB 的各种 cmets,这表明它不够出色;您只能获得 dict 样式的访问权限(如果您想选择某些日期范围或标题而不是 URL,该怎么办);它甚至不在 Python 3 的标准库集中。

【讨论】:

  • “它甚至不在 Python 3 的标准库集中。”。不知道,这是一个很好的观点,谢谢!
  • 请检查。我看了看,我可以看到 (g|n)dbm 支持,但我认为那是不同的,对吧?也许我记得在开发列表中的讨论与删除它有关。
【解决方案4】:

MongoDB 呢?我还没有尝试过,但它似乎很有趣。

【讨论】:

  • 看起来很有趣...不过似乎还不是很成熟。
【解决方案5】:

如果您只打算使用单个字段来查找记录,那么简单的键值存储将是一个不错的选择。将该单个字段(或任何其他唯一 ID)存储为您的键,将每条记录序列化为字符串(使用 JSON 或类似方法),并将该字符串存储为值。 Berkeley DB 无疑是键值存储的合理选择,但有许多替代方案可供选择: http://en.wikipedia.org/wiki/Dbm

如果您想按多个字段中的任何一个查找记录,SQLite 可能最适合开发目的。您将使用 SQL 编写查询,但不必维护数据库服务器。所有的多键机制都已经为你编写好了。

如果您真的想避免 SQL 或从数据存储中榨取所有性能,并且您想要多键访问,请考虑在键值之上添加一层额外的逻辑店铺。通过序列化记录并将每条记录的“列”值作为附加键插入,其值包含记录的“主”键,可以在键值存储之上构建类似列的行为。 (您有效地将键值存储用作记录字典和用于查找这些记录的索引字典。)Google 的 App Engine 就是这样做的。您可以自己执行此操作,也可以使用为您执行此操作的各种面向文档的数据库之一。对于一些有趣的阅读,尝试谷歌搜索“nosql”。 http://www.google.com/search?&q=nosql

【讨论】:

  • P.S.在 python 发行版中与 Berkeley DB 的交易只是 bdb 库内部的变化比 Python 开发人员想要跟上的更频繁。并不是说 Berekeley DB 不好,只是不方便直接集成到 python 版本中。您仍然可以将 bdb python 绑定作为单独的模块。
【解决方案6】:

好的,所以你说只是存储数据..?您真的只需要一个用于检索、查找、汇总等的数据库。因此,对于存储,只需使用简单的文本文件并附加行。如果需要,压缩数据,在字段之间使用分隔符 - 几乎任何语言都可以读取此类文件。如果您确实想要检索,那么请关注您的检索需求,按日期,按键,哪些键等。如果您想要简单的客户端,那么您需要简单的客户端数据库。 SQLite 比 BDB 容易得多,但看看 Sybase Advantage(对本地客户端非常快速且免费,但不是开源的)或 VistaDB 或 firebird 之类的东西......但所有这些都需要本地配置/设置/维护。如果您使用本地 XML 获取“大量”记录,则会给您一些不必要的臃肿文件大小..!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多