【问题标题】:Is MongoDB the right DB for a community site?MongoDB 是社区站点的正确数据库吗?
【发布时间】:2012-01-01 05:16:14
【问题描述】:

我正在使用 Node.JS 和 Express 创建一个社区站点,几乎所有快速教程或示例都使用 MongoDB,所以我检查了它。到目前为止,我使用的唯一数据库是 MySQL,但我对它不太熟悉,所以读 MongoDB 不会打扰我。 Mongo 看起来很不错,文档模型可能是有益的。有了猫鼬,它很容易使用。但是我有一些问题,所以如果 MongoDB 根本不适合我,我不会花很多时间学习使用它:

  1. 我了解到,如果您只在一台机器上使用 MongoDB,它是不可靠的,您可能会遇到数据丢失。那正确吗?这个项目并没有那么大,我买不起另一台服务器,数据丢失是绝对不行的!想象一下,一些论坛帖子消失了。但我想如果发生这种情况人们不会使用它。

  2. 该站点将包含一个自建论坛,我不确定关系数据库是否会更好。但是,您可以使用嵌入式帖子等保存线程。但是不知道如何搜索,因为 Mongo 不支持全文搜索。你怎么看?

  3. 什么时候在 Mongo 中使用嵌入文档?示例:用户可以在 Twitter 上发布状态更新。您会将这些更新保存在用户文档中吗?可以更新很多。还是每次更新的文档并将其链接到用户 ID? 3.1 以及如何跨多个文档进行查询?您想获取朋友的最近 10 次状态更新。您可以使用 MySQL 中的 JOIN 来做到这一点。

  4. 有没有办法像 MySQL 那样对文档使用自动增量 ID?例如,用户应该有一个唯一的整数键,但我不想要像 Mongo 那样的随机数,以保持用户 ID 较小。

  5. 如何处理猫鼬中的竞争条件?您从数据库加载文档,编辑某些内容并稍后保存。但也许同时它已经改变了。

【问题讨论】:

  • 如果你不知道mongoDB,为什么不学习呢? :-)
  • 其他人已经回答了您的问题 - 我只是想建议您尝试一下 MongoDB,因为它可以呼吸新鲜空气并且使用起来非常愉快。

标签: mongodb node.js mongoose


【解决方案1】:

分别解决每个问题:

  1. 不,这不再是真的。旧版本的 MongoDB 没有日志,但当前版本有,并且从 v. 2 开始,它默认被激活。但是,您应该在驱动程序级别使用SafeMode,以确保驱动程序和数据库之间的通信成功。

  2. 嵌入式帖子和线程可能不是最佳选择。我们构建了一个类似的东西,我们使用一个平面集合,每个帖子都存储 ParentId 和 ParentThreadId。嵌入有利有弊,但我们决定的论据是:

    a) 通常,我们只想获取站点范围内最新的 cmets 或给定线程中 n 个最新的 cmets,这两者都不能真正使用嵌入式文档来完成。

    b) 如果你有很多人同时写同一个主题,你需要小心并发。这可以解决,但我们觉得使用不会真正干扰的不同对象更安全,即使你犯了错误

    c) 正如 Joe 指出的那样,您必须在不同的系统中处理全文搜索。

  3. 如果您有很多更新,嵌入文档就不太适合,因为容器(包含嵌入对象的集合项)会增长。当它增长时,MongoDB 将不得不重新分配它,这可能需要更长的时间和碎片数据。

    3(a)。对于朋友的状态更新,使用扇出策略是有意义的。我answered a similar question yesterday

  4. 不要使用自动递增的数字。默认情况下,这是一个有缺陷的设计,因为它在分布式环境中并不能很好地工作。对于数据库,它是否存储一个具有值0x00000001int 或一个具有值0xfa9ac7335 的一个都没有区别。保持数字很小是没有意义的。我会选择 Mongo ObjectIdGuid/UUID。前者还包含一个时间戳。

  5. 我没用过mongoose,但总的来说,有悲观锁和乐观锁的典型策略。

【讨论】:

  • 感谢您的精彩回答!为什么我不应该使用自增数字?为什么它是一个有缺陷的设计?例如,我需要使用 URL 中的数字。一些随机的长十六进制数字看起来不太好。
  • 有很多反对顺序 id 的论据,这里有一些是我头顶的:a) 对于插入引用,你想知道 ref'd 对象的 id before i> 插入它,这样您就不会在数据库中丢失反向引用。 b) 自动增量 ID 可用于抓取您的网站、确定您的用户数量等。 c) 您可以找到“关闭”项目,这可能会泄露有关特定用户或对象的信息 d) 如果您需要合并集合,您需要重新分配主 ID 并更新所有引用 e) 主/主场景是不可能的(但 MongoDB 不是主/主)
【解决方案2】:
  1. 默认情况下,MongoDB 写入是一劳永逸的,因此如果出现问题,则可能会丢失数据。如果写入成功与否,您可以使用 SafeMode 给您一个响应,然后以您想要的任何方式处理它。话虽如此,我自己没有经历过任何丢失的数据。多台服务器将是用于故障转移的复制,如果一个节点出现故障,另一个节点可以自动提升为主节点。

  2. 如果你想要全文搜索,那么你不能用 Mongo 来做。您可以标记帖子中的每个单词并将每个单词存储在文档上的嵌入式数组中,您可以查询这些单词中的每个单词。问题是你没有相关性。您可以使用 Map Reduce 构建一些相关性逻辑,但这会减慢您的查询速度。如果你真的想要快速的全文搜索,你应该看看 SOLR 或 Elastic Search。

  3. 就我个人而言,我不会将状态更新存储在嵌入式文档中,而是将它们全部放在带有用户标识符的单独集合中。 Mongo 中没有连接,因此您必须执行两个查询,一个获取您朋友的 ID,另一个获取状态更新。根据您的集合的大小,如果有正确的索引,这将非常快,即使它是两个查询。

  4. 我认为您不能在 Mongo 级别对 ID 使用自动递增整数。您可以在应用程序中自己处理它,因为您可以使用任何字段作为标识符。添加新文档时,您必须查询集合以获取最高 ID 并增加它。 Mongo 对象 ID 由机器 ID、进程 ID、时间戳和一些随机性组成,以创建唯一密钥。

  5. 我不熟悉 Mongoose。

【讨论】:

    【解决方案3】:

    以下是 NoSQL 数据库的比较,显示了它们的优势、劣势和最适合的项目类型: http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis

    【讨论】:

      猜你喜欢
      • 2021-03-18
      • 1970-01-01
      • 2018-10-10
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 2010-11-25
      • 2011-09-14
      • 2016-07-24
      相关资源
      最近更新 更多