【问题标题】:mysql v mongodb - best solution for a complex user focussed site?mysql v mongodb - 以用户为中心的复杂网站的最佳解决方案?
【发布时间】:2011-02-18 17:16:52
【问题描述】:

我花了几天时间研究 mysql 与 nosql 解决方案(特别是 mongodb)在我的项目中的优缺点。

该项目最终需要能够扩展以同时处理数以万计的用户——总共数百万用户。该站点以用户为中心,并且与数据库的交互次数与 facebook 之类的站点一样多——它是非常相关的,所有功能都取决于与用户的关系以及他们与其他用户的关系。它还包含大量数据 - 大量文件、图像、音频、消息、个人新闻提要等。

我非常喜欢 mongodb 上的外观,我喜欢它的工作方式,我喜欢它的扩展方式 - 但我无法理解这对于诸如此类的网站如何工作我描述。特定用户的所有交互是否都必须存储在单个文档中?

然而,我非常喜欢使用 mysql 并且喜欢它的关系方面。我只是担心如果没有大量工作,这个项目会出现可扩展性问题——尽管也许使用 memcached 和分片这不会成为问题?

我想从那些对大型项目的两个数据库有经验的人那里知道,mysql 和 mongodb 哪个工具适合这项特殊工作?

【问题讨论】:

    标签: mysql mongodb performance scale database


    【解决方案1】:

    如果数据是高度相关的,请使用关系数据库。如果不是,不要。 NoSQL 很棒,不要误会我的意思,但它并不适合所有任务。它可能适合您的任务,但找出答案的唯一方法是为您的特定用例构建一些测试。添加一堆虚拟数据(数百万行,如果不是数亿行)。然后对其进行负载测试。

    就扩展而言,这更多是您构建应用程序的一个组成部分,而不是您选择的后端。你有一个可靠的模式吗?您是否有一个带有直写缓存的强大缓存层?您是否尽可能高效地访问后端(查询等)?你可以根据你的应用进行分片吗?

    这些是适合这里的问题。不是“这对我来说会更好”。而不是“哪个是正确的工具”。两者都可以做得很好。哪个最好取决于您...

    【讨论】:

    • 我也是新手,但我的印象是,无论您的应用程序如何设置,Mongo 都会分片。应用程序/客户端正在使用 Mongo 路由器,并且不知道 MongoDB 是否已分片。尽管我同意,如果您必须扩展项目的一部分,那么您很可能也必须扩展另一部分。
    • 但是对于 mysql,如果我在只有几行的表上有很多连接的查询,这将比在数百万行的表上执行相同的查询更好。而 mongodb 的数据量对速度的影响不大?那是缩放对吗?或者您是说如果 mysql 数据库构建良好并且规范化/非规范化良好,那么这将与查询大型 mongodb 文档一样快?
    • @Colin:性能是相对的。问题不在于 solution x 在较小的集合上是否会比较大的集合表现更好。所有解决方案将随着数据的增多而变慢。这是野兽的本性。相反,重要的是解决方案如何随更多数据扩展。传统数据库中智能设计的查询和模式应该可以很好地扩展。单行/文档查找将尽可能快地使用任一系统(并且两者的规模大致相同)。不同之处在于更复杂的操作。您选择哪一个将取决于您的应用程序和技能。
    【解决方案2】:

    显然,这里没有灵丹妙药。但是,我想挑战您所做的这一假设:

    ...这是非常相关的,所有功能都取决于与用户的关系以及他们与其他用户的关系...

    好的,我希望您想象一下关系数据库中有 1 亿用户并开始构建此模型。让我们尝试一些简单的事情,获取用户朋友的姓名。

    如何获得用户的朋友?那么你去users_friends 表。如果每个用户只有 10 个朋友,那么该表包含十亿行。如果用户有更合理的 100 个朋友,那么您现在有 10B 行。

    所以现在您有了一个用户和一个他们的朋友 ID 列表。我们如何得到他们朋友的名字?好吧,您浏览 100 个 ID 的列表并拉下每个朋友。完美。

    所以现在,如果您想向一位用户显示他们所有朋友的姓名,您所要做的就是将 100M 记录表连接到 10B 记录表。 这不是一个简单的任务。随着数据集的增长,扩展连接变得更加困难和昂贵。

    因此,为了使这更容易,您可能会运行for 循环并手动收集每个朋友的记录。您必须这样做,因为朋友分散在多个服务器上,因此每个“查找”都必须单独完成。

    你已经破坏了你的“关系模型”。

    朋友列表呢?保存 10B 条记录的表格真的很实用吗?为什么不为每个用户保留一份好友 ID 列表?为什么要额外查询。

    如果您注意到这里的模式,我们基本上已经将 “非常相关” 模型分解为有效的键值查找。当然,键值模型会更好地扩展。因此,MongoDB 似乎很适合这里。

    不要误会我的意思,关系数据库有很多很好的用途。但是,当您谈论处理数百万个单独的键值样式请求时,您可能希望查看 NoSQL 数据库。

    【讨论】:

    • 我经常在 100M 行表和 50 亿行表之间运行连接。你能解释一下为什么join 根本行不通吗?尤其是因为 RDBMS 系统每天每一秒都在世界各地的庄园中使用......
    • MongoDB 中的键值查找与通过 RDBMS 中的主键检索每个原始数据有何不同?只是好奇。
    • 这听起来不错,也很有意义——所以在 mongodb 中,因为我们没有连接,所以每个用户和与他们相关的所有数据都必须在一个文档中吗?或者因为每个文档只能比每个用户多 4mb 一个集合?所以我们会有一个名为 user_[name] 的集合和一个名为 friends 的文档?
    • @colin:MongoDB 文档现在最大为 16MB(截至 1.8.0)。 4MB = 100 份战争与和平,这是很多文字。您可能应该对一个用户集合没问题。此外,您可以合理创建的集合数量是有限的。
    • @gates 这是真的!如果每个用户都可以上传无限的照片/音频呢?
    【解决方案3】:

    没有法律规定您必须使用完全一个数据库构建应用程序。为特定任务配备专用后端通常是常见的做法。例如。在类似 Facebook 的应用程序的上下文中,使用图形数据库来存储用户之间的关系可能是有意义的——每个数据库都有其优点和缺点,只有傻瓜才会只使用 RDBMS 或仅使用 NoSQL db 来实现大型后端因为他们不知道更好。

    【讨论】:

    • 是的,这很可能是解决方案。所以我们可以从 mysql 开始,然后当我们识别出昂贵的表/查询时,将这些部分移动到像 mongodb 这样更具可扩展性的东西?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 2011-01-20
    相关资源
    最近更新 更多