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

Using MongoDB vs MySQL with lots of JSON fields?

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

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

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

例如。

1
2
3
4
5
6
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字段,序列为:

  • 阅读python脚本中的JSON。

  • 更新JSON

  • 将JSON存储回MySQL。

  • 它应该是MongoDB中的单个操作,具有$push$inc$pull等原子操作。此外
    MongoDB的文档结构很适合我的数据。

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

    关于MySQL:

  • 稳定而熟悉。
  • 备份和恢复很容易。
  • 使用某些字段作为无模式JSON可以避免某些未来的模式更改。
  • 可能要早点使用memcached层。
  • JSON blobs在一些表中将是静态的,例如主帖,但是在其他一些表中会更新,例如P??ost投票和喜欢。
  • 关于MongoDB:

  • 更适合将架构较少的数据存储为文档。
  • 可以避免缓存直到稍后阶段。
  • 有时应用程序可能会变得更加密集,MongoDB可以在不安全写入不成问题的那些点上表现更好。
  • 不确定稳定性和可靠性。
  • 不确定备份和恢复有多容易。
  • 问题:

  • 如果有一半数据是无模式的,我们应该选择MongoDB吗?如果使用MySQL,我们是否存储为JSON?
  • 一些数据如主要帖子是关键的,所以它将使用安全写入,计数器等保存
    将使用不安全的写入保存。此政策是否基于数据的重要性,写密集性是否正确?

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

  • 稳定性,备份,快照,恢复,更广泛的采用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


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

    Shall we chose mongodb if half of data is schemaless, and is being stored as JSON if using MySQL?

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

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

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

    Some of the data like main posts is critical , so it will be saved using safe writes , the counters etc will be saved using unsafe writes. Is this policy based on importance of data, and write intensiveness correct?

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

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

    How easy is it to monitor,backup and restore Mongodb as compared to mysql? We need to plan periodic backups (say daily), and restore them with ease in case of disaster. What are the best options I have with mongoDb to make it a safe bet for the application?

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

    Stability,backup,snapshots,restoring,wider adoption i.e.database durability are the reasons pointing me to use MySQL as RDBMS+NoSql even though a NoSQL document storage could serve my purpose better.

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

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

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


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

    备份

    这里的文档非常详尽,涵盖了很多方面:

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

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

    Early days so far: it's just a glorified shell script and needs way more error checking. But already it works for me and I figured I'd share the joy. Bug reports, patches & suggestions welcome.

    从这里获取一份副本。

    还原

    • 格式等

    mongodump完全记录在这里,mongorestore就在这里。

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

    监控

    记录在这里。

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

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

    我听说有些人看着Zappix但是我从来没有用过它所以不能发表评论。

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

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


    使用存储的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