使用MongoDB与MySQL有很多JSON字段?

时间:2012-10-17 12:30:02

标签: mysql mongodb nosql

有微博类型的应用程序。默认的两个主要基本数据库存储是: MySQL或MongoDB。

我计划对大量数据进行非规范化。对帖子进行的投票存储在投票表中,计数也在主帖子表中递增。该帖还涉及其他行动(例如,喜欢,投票放弃)。

如果我使用MySQL,一些数据更适合作为JSON而不是固定模式,以便更快地进行查找。

E.g。

POST_ID   |  activity_data

213423424 | { 'likes': {'count':213,'recent_likers' :
             ['john','jack',..fixed list of recent N users]} , 'smiles' : 
             {'count':345,'recent_smilers' :
             ['mary','jack',..fixed list of recent N users]}  }

该应用程序还有其他组件,其中提出了JSON的使用。 因此,要更新JSON字段,序列为:

  1. 在python脚本中读取JSON。

  2. 更新JSON

  3. 将JSON存储回MySQL。

  4. 在MongoDB中使用$push$inc$pull等原子操作进行单一操作。 MongoDB的文档结构很适合我的数据。

    选择数据存储时的注意事项。

    关于MySQL:

    1. 稳定而熟悉。
    2. 备份和恢复很简单。
    3. 使用某些字段作为无模式JSON可以避免某些未来的模式更改。
    4. 可能必须尽早使用memcached层。
    5. JSON blobs在某些表中会像主帖一样是静态的,但是会在其他一些表中更新,例如P​​ost投票和喜欢。
    6. 关于MongoDB:

      1. 更适合将架构较少的数据存储为文档。
      2. 可以避免缓存直到后期。
      3. 有时候应用程序可能会变得更加密集,MongoDB可以在不安全写入不成问题的地方表现更好。
      4. 不确定稳定性和可靠性。
      5. 不确定备份和恢复的容易程度。
      6. 问题:

        1. 如果有一半的数据是无模式的,我们选择MongoDB,如果使用MySQL,我们会以JSON的形式存储吗?
        2. 主要帖子等一些数据很关键,因此会使用安全写入,计数器等进行保存 将使用不安全的写入保存。此政策是否基于数据的重要性,写密集性是否正确?

        3. 与MySQL相比,监控,备份和恢复MongoDB有多容易?我们需要计划定期备份(比如每天),并在发生灾难时轻松恢复。我使用MongoDB的最佳选择是使应用程序安全可靠。

        4. 稳定性,备份,快照,恢复,更广泛的采用I.e.database持久性是指向我的原因 使用MySQL作为RDBMS + NoSql,即使NoSQL文档存储可以更好地满足我的目的。

          考虑到我想到的数据库设计,请关注MySQL和MongoDB之间的选择。我知道可以有更好的方法来使用RDBMS或MongoDB文档来规划数据库设计。但这不是我问题的当前焦点。

          更新:从MySQL 5.7开始, MySQL支持丰富的本机JSON数据类型,它提供了数据灵活性以及丰富的JSON查询。

          https://dev.mysql.com/doc/refman/5.7/en/json.html

3 个答案:

答案 0 :(得分:15)

所以,直接回答问题......

  

如果有一半的数据是无模式的,我们选择mongodb,如果使用MySQL,我们会以JSON的形式存储吗?

Schemaless存储肯定是使用MongoDB的一个令人信服的理由,但正如您所指出的,将JSON存储在RDBMS中也相当容易。 MongoDB背后的力量在于对无模式存储的丰富查询。

如果我可以在插图中指出有关更新JSON字段的一个小缺陷,那不仅仅是获取当前值,更新文档然后将其推回数据库。该过程必须全部包含在事务中。在您开始对数据库进行非规范化之前,事务往往相当简单。然后像记录upvote这样简单的东西可以锁定整个模式的表。

使用MongoDB,没有交易。但是,操作几乎总是以允许原子更新的方式构建。这通常涉及SQL范例的一些戏剧性转变,但在我看来,一旦你停止尝试强制对象进入表格,它们就相当明显。至少,许多其他人遇到了你将面临的同样问题,而Mongo社区往往对他们所克服的挑战相当开放和直言不讳。

  

主要帖子等一些数据很关键,因此使用安全写入保存,计数器等将使用不安全写入保存。此政策是否基于数据的重要性,写密集性是否正确?

通过“安全写入”我假设你是指在每次写入后打开自动“getLastError()”的选项。我们在DBCollection上有一个非常薄的包装器,允许我们在调用getLastError()时进行细粒度控制。但是,我们的策略不是基于“重要”数据的方式,而是基于查询后面的代码是否期望在以下读取中立即显示任何修改。

一般来说,这仍然是一个糟糕的指标,我们已经迁移到findAndModify()以获得相同的行为。在我们仍然显式调用getLastError()的情况下,数据库可能会拒绝写入,例如当我们使用可能重复的_id插入()时。

  

与mysql相比,监视,备份和恢复Mongodb有多容易?我们需要计划定期备份(比如每天),并在发生灾难时轻松恢复。我使用mongoDb的最佳选择是什么才能使它成为应用程序的安全赌注?

我恐怕无法谈论我们的备份/恢复政策是否有效,因为我们还没有恢复。我们正在遵循MongoDB的备份建议; @ mark-hillick在总结这些方面做得很好。我们正在使用副本集,我们已经迁移了MongoDB版本以及引入了新的副本成员。到目前为止,我们没有停机时间,所以我不确定我能说得好。

  

稳定性,备份,快照,恢复,更广泛的采用,即数据库持久性是指向我使用MySQL作为RDBMS + NoSql的原因,即使NoSQL文档存储可以更好地服务于我的目的。

因此,根据我的经验,MongoDB提供了无模式数据的存储,其中包含一组足够丰富的查询原语,以便通常可以用原子操作替换事务。很难忘掉10年以上的SQL经验,但我遇到的每个问题都已经由社区或10gen直接解决。我们没有丢失数据或没有任何我能记得的停机时间。

简而言之,MongoDB是我在查询,维护,可扩展性和可靠性方面所使用的最佳数据存储生态系统。除非我的应用程序具有如此明显的关系性,否则我无法使用除SQL之外的其他任何东西,我会尽一切努力使用MongoDB。

我不为10gen工作,但我非常感谢那些做过的人。

答案 1 :(得分:12)

我不会对比较发表评论(我为10gen工作并且认为这对我来说不合适),但是,我会回答具体的MongoDB问题,以便您更好地做出决定。

返回-向上

文档here非常详尽,涵盖了很多方面:

  • 块级方法(LVM使它变得非常容易,并且很多人都这样做)
  • 有/无日记
  • EBS快照
  • 常规快照
  • 复制(技术上没有备份,但很多人都使用副本集进行冗余和备份 - 不建议这样做但是已经完成了)

直到最近,没有相当于mylvmbackup的MongoDB,但是一个好人写了一个:)用他的话来说

  

到目前为止的早期:它只是一个美化的shell脚本,需要更多的错误检查。但它已经对我有用了,我想我会分享快乐。错误报告,补丁和补丁建议欢迎。

here获取副本。

<强>恢复

mongodump已完整记录here,mongorestore为here

mongodump不包含索引,但包含system.indexes集合,因此mongorestore可以在还原bson文件时重建索引。 bson文件是实际数据,而mongoexport/mongoimport不是类型安全的,所以它可以是任何东西(从技术上讲):)

<强>监控

记录here

我喜欢Cacti,但afaik,Cacti模板没有跟上MongoDB的变化,因此依赖于旧的语法,所以发布2.0.4后,我相信存在问题。

Nagios运作良好,但它是Nagios,所以你要么爱,要么恨它。很多人都使用Nagios,它似乎为他们提供了很好的可视性。

我听说有些人在看Zappix,但我从未使用它,所以无法发表评论。

此外,您可以使用MMS,它是免费的,并在外部托管。您的MongoDB实例运行代理,其中一个代理通过https与mms.10gen.com进行通信(使用python代码)。我们使用MMS来查看MongoDB实例的所有性能统计数据,从高级别的广泛视图以及提供向下钻取的能力非常有用。它安装简单,您不必为此运行任何硬件。许多客户运行它,有些客户使用Cacti / Nagios进行补充。

可以找到有关MMS的帮助信息here(这是一份非常详细,包容性的文件)。

答案 2 :(得分:4)

存储json的mysql解决方案的一个缺点是,您将无法有效地搜索json数据。如果将它全部存储在mongodb中,则可以对包括json在内的所有数据创建索引和/或查询。

Mongo的编写工作非常好,而且你唯一输入的东西是mysql是事务支持,因此能够回滚多部分保存。但是,如果您能够在原子操作中提交更改,则不存在数据安全问题。如果你被复制,mongo提供了“最终一致”的承诺,这样奴隶最终将镜像主人。

Mongodb不提供某些db构造(如外键)的本机强制或级联,因此您必须自己管理(例如通过组合,这是mongo的强项之一),或者通过使用dbrefs。

如果您真的需要事务支持和强大的“安全”写入,但仍然需要nosql提供的灵活性,您可以考虑使用混合解决方案。这将允许您使用mysql作为主要的帖子商店,然后使用mongodb作为您的“无模式”商店。这是一个讨论混合mongo / rdbms解决方案的文档的链接:http://www.10gen.com/events/hybrid-applications该文章来自10gen的网站,但你可以通过快速谷歌搜索找到其他例子。

更新5/28/2019

自从这个答案发布以来,MySQL和Mongodb都进行了一些更改,因此它们之间的优缺点变得更加模糊。这个更新对原始问题没有帮助,但我这样做是为了确保任何新读者都能获得更多最新信息。

MongoDB现在支持交易:https://docs.mongodb.com/manual/core/transactions/

MySql现在支持索引和搜索json字段: https://dev.mysql.com/doc/refman/5.7/en/json.html