何时使用MongoDB或其他面向文档的数据库系统?[关闭]


516

我们提供了一个用于视频和音频剪辑,照片和矢量图像的平台。我们从MySQL作为数据库后端开始,最近加入了MongoDB来存储文件的所有元信息,因为MongoDB更符合要求。例如:照片可能具有Exif信息,视频也可能具有音轨,我们也想在其中存储元信息。视频和矢量图形不共享任何常见的元信息等。因此,我知道MongoDB非常适合存储此非结构化数据并使其可搜索。

但是,我们将继续开发平台并添加功能。现在,下一步就是为我们的用户提供一个论坛。现在出现的问题是:使用MySQL数据库,这对于存储论坛和论坛帖子等是一个不错的选择,还是为此使用MongoDB?

所以问题是:何时使用MongoDB以及何时使用RDBMS。如果可以选择的话,您会选择mongoDB还是MySQL?为什么选择它?


12
不知道为什么明显没有将其标记为基于意见。这里有明确的是非题。
Spencer 2014年

Answers:


659

NoSQL中:如果这么简单,作者将写有关MongoDB的文章:

MongoDB不是键/值存储,它还有很多。绝对不是RDBMS。我没有在生产中使用过MongoDB,但我在构建测试应用程序时就使用了它,这是一个非常酷的工具包。它似乎非常有效,并且具有或将很快具有容错能力和自动分片功能(也可以扩展)。我认为,Mongo可能是迄今为止我所见过的最接近RDBMS替代品的产品。它不适用于所有数据集和访问模式,但它是为典型的CRUD设计的。大多数人使用关系数据库来存储本质上是一个巨大的哈希,并能够在任何这些键上进行选择。如果您的数据库是3NF,并且您不执行任何联接(您只是选择一堆表并将所有对象放在一起,这就是大多数人在Web应用程序中所做的事情),那么MongoDB可能会为您踢屁股。

然后,在结论中:

真正要指出的是,如果您因为无法选择数据库而无法制作出超棒的东西,那说明您做错了。如果您知道mysql,请使用它。在实际需要时进行优化。像ak / v商店一样使用它,像rdbms一样使用它,但是出于上帝的缘故,构建您的杀手级应用程序!这与大多数应用无关。Facebook仍然大量使用MySQL。维基百科经常使用MySQL。FriendFeed大量使用MySQL。NoSQL是一个很棒的工具,但是它肯定不会成为您的竞争优势,也不会使您的应用程序变得炙手可热,最重要的是,您的用户不会在意这些。

我要如何构建下一个应用程序?大概是Postgres。我会使用NoSQL吗?也许。我可能还会使用Hadoop和Hive。我可能会将所有内容保存在平面文件中。也许我会开始在Maglev上进行黑客攻击。我将使用最适合该工作的东西。 如果我需要报告,则不会使用任何NoSQL。如果需要缓存,则可能会使用Tokyo Tyrant。如果需要ACIDity,则不会使用NoSQL。如果我需要大量的计数器,我将使用Redis。如果我需要交易,我将使用Postgres。 如果我有大量的单一类型的文档,则可能会使用Mongo。如果我每天需要编写10亿个对象,则可能会使用Voldemort。如果我需要全文搜索,则可能会使用Solr。如果我需要对易失性数据进行全文搜索,则可能会使用Sphinx。

我喜欢这篇文章,我发现它非常有用,它很好地概述了NoSQL的概况和炒作。但是,那是最重要的部分,它确实有助于在RDBMS和NoSQL之间进行选择时问自己正确的问题。值得一读的恕我直言。

替代文章链接


4
谢谢,这确实是一篇非常有趣的文章。
极光


48
@iddqd ROFL!伙计,这太好笑了。/dev/null D
Pascal Thivent

3
感谢您对炒作的了解。
守护进程

2
希望BJ Clark不会选择在同一项目中使用所有这些技术。那将是一个学习曲线。
亚当·蒙森

186

在将MongoDb用于社交应用程序两年后,我见证了没有SQL RDBMS的生活真正意味着什么。

  1. 您最终要写作业来做一些事情,例如连接来自不同表/集合的数据,而RDBMS会自动为您做这些事情。
  2. 您使用NoSQL的查询功能严重受损。MongoDb可能是最接近SQL的东西,但仍然远远落后于SQL。相信我。SQL查询超级直观,灵活而强大。MongoDb查询不是。
  3. MongoDb查询只能从一个集合中检索数据,并且只能利用一个索引。MongoDb可能是最灵活的NoSQL数据库之一。在许多情况下,这意味着需要更多往返服务器才能找到相关记录。然后开始对数据进行非规范化-这意味着后台作业。
  4. 它不是关系数据库这一事实意味着您将没有外键约束(某些人认为它们表现不佳)以确保数据一致。我向您保证,这最终将在您的数据库中造成数据不一致。做好准备 您很可能会开始编写流程或检查以保持数据库的一致性,这可能不会比让RDBMS为您做的更好。
  5. 忘记像休眠这样的成熟框架。

我相信,使用典型的SQL RDBMS,所有项目中的98%可能比使用NoSQL更好。


10
有趣的想法...
luigi7up

3
另一方面,查询功能和您描述的联接不应该成为问题:如果您使用MongoDB,那么您仍然必须做一些工作来设计您的集合以及将要放入的数据,这样您就不需要复杂联接等。无论如何,数据库不是瓶颈,对于某些用例,存在像Memcache这样的变通方法。但是,如果从头开始,您可能会发现设计和使用MongoDB更简单,更快捷(作为使用对象代码的开发人员,我不需要ORM)。当然,您必须编写一些脚本,但实际上并不难,并且可以重复使用代码
Aki

1
大多数人不会将NoSQL数据库用于为其创建的特定用例,此后便重新发明了许多轮子。该的NoSQL与SQL辩论表明,许多人遇到使用NoSQL的,好像他们是要回20 - 30年的时间,以预科德,前关系,预SQL倍。或者,就像迈克尔·斯通布雷克(Michael Stonebraker)所说的那样:“发生的事情来了”
Lukas Eder

1
第3项“仅利用一个索引”是否仍然有效?我现在刚刚进入MongoDB,从到目前为止我所读/查看的内容来看,它似乎可以支持多个索引?
Jeach

1
@Jeach:不,#3不再正确。MongoDB 2.6引入了索引交集
罗伯·加里森

26

存储这些非结构化数据

如您所说,MongoDB最适合存储非结构化数据。这样可以将您的数据整理成文档格式。这些称为NoSQL数据存储区(MongoDBCouchDBVoldemort)的RDBMS替代方案对于大规模扩展并需要从这些大数据存储区更快地访问数据的应用程序非常有用。

这些数据库的实现比常规的RDBMS更简单。由于这些是简单的键值或文档样式的二进制对象,因此直接序列化到磁盘中。这些数据存储不会强制使用ACID属性和任何模式。这不提供任何交易功能。因此,这可以扩大规模,并且我们可以实现更快的访问(读取和写入)。

但是相比之下,RDBM对数据执行ACID和架构。如果您想使用结构化数据,则可以继续使用RDBM。

我会选择MySQL创建此类论坛。因为这不会扩大规模。这是一个非常简单(通用)的应用程序,具有数据之间的结构化关系。


10
“我会选择mysql创建论坛之类的东西。” 真?我认为使用论坛文档比使用关系文档要容易得多,而使用关系文档(如果您是从头开始编写)的话。如果您不特别需要RDBMS的功能,那么我想说MongoDB或类似的数据库,以便于使用和扩展。
Sasha Chedygov


2018年:MongoDB也支持ACID
Nepoxx

10

请注意,Mongo本质上存储JSON。如果您的应用程序要处理大量的JS对象(带有嵌套),并且您想保留这些对象,那么使用Mongo的理由很强烈。它使您的DAL和MVC层超薄,因为它们不会解包所有JS对象属性,而是试图将它们强制拟合为它们自然不适合的结构(模式)。

我们的系统的核心是几个复杂的JS对象,我们喜欢Mongo,因为我们可以真正,非常轻松地持久存储所有内容。我们的对象也相当无定形且没有结构,Mongo吸收了这种复杂性而不会眨眼。我们有一个自定义的报告层,可以解密供人类使用的非晶体数据,并且开发起来并不难。


7

如果您需要复杂的事务,我会说使用RDBMS。否则,我会选择MongoDB-更灵活地使用它,并且您知道它可以在需要时进行扩展。(尽管我有偏见-我从事MongoDB项目)


7
复杂的事务在MongoDB中不起作用,但在其他NoSQL数据库(例如MarkLogic)中也起作用(自从我为MarkLogic运行开发人员社区以来,我也有偏见)。
埃里克·布洛赫

感谢您对MarkLogic的提示-我不知道。
奥罗拉

我希望听到mdirolf的来信。为什么MongoDB选择不执行事务?
Aki

7

谁需要分布式的分论坛?也许是Facebook,但是除非您要创建Facebook竞争对手,否则请使用Mysql,Postgres或您最喜欢的任何工具。如果您想尝试MongoDB,可以,但是不要指望它会为您带来魔力。就像其他所有内容一样,它也会有怪癖和一般的麻烦,因为我敢肯定,您已经发现您是否真的已经在进行这项工作。

当然,MongoDB可能会大肆宣传,从表面上看似乎很容易,但是您会遇到更成熟的产品已经克服的问题。不要轻易被吸引,而要等到“ nosql”成熟或死亡。

就个人而言,我认为“ nosql”将因碎片而枯萎和死亡,因为没有固定的标准(几乎是按定义)。因此,我不会在任何长期项目上亲自下注。

在我的书中唯一可以保存“ nosql”的东西是,它是否可以无缝地集成到Ruby或类似语言中,并使该语言“持久”,几乎不需要编码和设计上的任何开销。那也许会过去,但是我要等到那时,而不是现在,当然它需要变得更加成熟。

顺便说一句,为什么要从头开始创建论坛?可以调整许多吨的开源论坛以满足大多数需求,除非您确实创建了下一代论坛(我对此表示怀疑)。


5
感谢您的回答。集成论坛是一个烂摊子-我们已经做到了,并决定不再采用这种方式:我们不需要成千上万的功能,而需要在软件中进行完全集成。
奥罗拉

4

我已经看到很多公司都在使用MongoDB进行应用程序日志的实时分析。它的无模式性确实适合于应用程序日志,其中记录模式往往会随时更改。此外,其“ 封顶收集”功能很有用,因为它会自动清除旧数据以使数据适合内存。

我确实认为这是MongoDB合适的领域,但是通常更建议使用MySQL / PostgreSQL。网络上有很多文档和开发人员资源,以及它们的功能和健壮性。


4

您可能更喜欢Mongo的2个主要原因是

  • 模式设计的灵活性(JSON类型文档存储)。
  • 可扩展性-只需添加节点,它就可以很好地水平扩展。

适用于大数据应用。RDBMS不适用于大数据。


3

您知道,关于连接和“复杂事务”的所有这些东西-但很多年前,正是Monty自己解释了COMMIT / ROLLBACK的“需求”,说“所有这些都是在逻辑类中完成的” (而不是数据库)”,因此又是一回事。现在需要的是一种笨拙而又令人难以置信的整洁,快速的数据存储/检索引擎,以完成99%的Web应用程序。


谢谢,您在这里提出了一个有趣的观点。我真的会对Monty的解释感兴趣,因为我不确定跨多个表的更新回滚在纯应用程序逻辑中有多么复杂-我不确定,是否真的可能?
aurora

我也不确定“最佳”方式。我们一直只是跟踪对数据库所做的所有事情,然后在应用程序级别以代码形式允许或撤消它。我们从未在任何地方,任何时候都依赖交易。Mongo文档建议使用元数据来跟踪发生可回滚事务的哪些部分,事务处于什么状态,以防事务中断并需要回滚。有趣的是,我们已经与MySQL等一起做过。它的工作量并没有那么多,而是将精力集中在正在发生的事情,何时,何地以及为什么上,而不是将其置于黑盒中。
2011年

在10gen网站的某处有关于此的注释...提到如何手动使用“互锁”字段或“棘轮”来指示多步过程的状态。在我看来,如果您放大MySQL引擎本身,那么无论如何,“块事务”仍将扩展为一系列步骤。只是以比在数据库字段中手动进行跟踪更小,更快的方式完成了互锁或棘轮操作。
2012年

我们还没有找到一种限制MongoDB守护程序的好方法-它吞噬了几乎所有可用RAM,用于其索引和数据存储在内存中,尽管它会在其他proc需要它时快速产生内存。不过,最好有一个'use_max_memory'或其他易于定义的限制,以确保MongoDB不会失控并使服务器陷入交换颠簸状态(即使在最新版本中,我们也已多次看到)。至少MySQL接受各种可定义的限制和操作提示。
2012年

没有直接关系,但是有点类似:我们正在使用memcached,但是由于仍未解决的Memcache / Memcached PHP驱动程序惨败而放弃了它。我们使用MongoDB作为快速的临时key:val存储(它非常有用!),直到发现apc_store()多么快捷和容易。如果我们发现APC充满了我们曾经存储在memcached中的临时树桩(相对于存储的预编译PHP),我们将恢复到MongoDB进行key:val存储。
2012年

1

如前所述,您可以在很多选择之间进行选择,看看所有这些选择:http : //kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis

我的建议是找到最佳的组合:MySQL + Memcache如果需要ACID并想加入一些表真的很棒,MongoDB + Redis非常适合文档存储Neo4J非常适合图数据库

我该做什么:我从MySQl + Memcache开始,因为我习惯了,然后开始使用其他数据库框架。在单个项目中,您可以将MySQL和MongoDB例如结合在一起!


MySQL + memcached将为您带来最终的一致性。我不认为在RDMB上下文中使用ACID。
R. van Twisk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.