MongoDB是社区网站的正确DB吗?

我正在用Node.JS和Express创build一个社区站点,几乎所有的快速教程或示例都使用MongoDB,所以我查了一下。 到目前为止我使用的唯一的数据库是MySQL,但是我对它并不是很熟悉,所以不会读入MongoDB。 Mongo看起来相当不错,文档模型可能是有益的。 和mongoose一起使用很简单。 但是我有一些问题,所以如果不适合的话,我不花很多时间学习使用MongoDB:

  1. 我读过MongoDB是不可靠的,如果你只在一台机器上使用它,你可能会遇到数据丢失。 是对的吗? 该项目不是那么大,我可以承受另一台服务器和数据丢失是完全不行! 想象一下一些论坛post就消失了。 但是我想人们不会在这种情况下使用它。

  2. 该网站将包含一个自我构build的论坛,我不知道如果关系数据库会更好。 但是,您可以保存embedded式post的线程等。 但不知道如何searchMongo不支持全文search。 你怎么看?

  3. 什么时候在Mongo中使用embedded式文档? 示例:用户可以像在Twitter上一样发布状态更新。 你会将这些更新保存在用户文档中吗? 可以有很多更新。 或每更新一个文件,并将其链接到用户ID? 3.1如何查询多个文档? 你想获取你的朋友的最后10个状态更新。 你可以用MySQL中的JOIN来完成。

  4. 有没有办法使用MySQL中的文档的自动增量ID? 例如一个用户应该有一个唯一的整数密钥,但我不希望一些像Mongo这样的随机数字,为了保持用户ID很小。

  5. 你如何处理mongoose的竞争条件? 你从数据库中加载一个文档,编辑一些东西并稍后保存。 但也许它已经在同一时间改变了。

分别解决每个问题:

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

  2. embedded的post和线程可能不是最好的select。 我们已经构build了一个类似的东西,我们正在使用一个平面集合,每个post存储ParentId和ParentThreadId。 有embedded的优点和缺点,但我们的决定是:

    a)通常,我们只想在给定的线程中获取最近的评论或最近的评论,而这两者都不能使用embedded式文档来完成。

    b)如果你有很多人同时写同一个话题,你需要小心并发。 这是可以解决的,但是即使你犯了错误,我们也可以使用不会干扰的不同对象来保证安全

    c)正如Joe所指出的,你必须在不同的系统中处理全文search。

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

    图3(a)。 对于朋友的状态更新,使用扇出策略是有道理的。 我昨天回答了一个类似的问题 。

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

  5. 我没有使用mongoose,但总的来说,有一些典型的悲观和乐观locking策略。

  1. 默认情况下,MongoDB的写入是火灾和遗忘,所以如果出现问题,就有可能丢失数据。 您可以使用SafeMode,如果写入成功或不成功,就会给出响应,然后以任何您想要的方式处理它。 说了我自己没有经历过任何丢失的数据。 多个服务器是用于故障转移的复制,如果一个节点掉下来,可以自动升级为主节点。

  2. 如果你想全文search,那么你不能真的与Mongo做。 你可以在文章中标记每个单词,并将每个单词存储在文档中的embedded数组中,这些数据将被索引,您可以查询每个单词。 那么问题就是你没有相关性。 您可以使用Map Reduce构build一些相关性逻辑,但是这会降低查询速度。 如果你真的想快速全文search,你应该看看SOLR或弹性search。

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

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

  5. 我不熟悉mongoose。

下面是NoSQL数据库的比较,显示了它们最适合的强度,弱点和项目types: http ://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis