【问题标题】:Making a blog; can't decide between MongoDB and MySQL [closed]制作博客;无法在 MongoDB 和 MySQL 之间做出决定 [关闭]
【发布时间】:2012-10-17 18:57:58
【问题描述】:

好的,所以我即将开始使用 Node.js 为我的网站写博客(就像一个学习过程一样),我一直在激烈地与自己争论使用 MySQL 或 MongoDB 中的哪一个.

四处搜索产生了一些“如何在 Mongo 中写博客”指南,但它们似乎并未涵盖我遇到的问题。这是我的困境:

如果我要使用 MySQL,我会想象我的架构是这样的:

帖子:

ID, USER, DATE, TITLE, TAGS

评论:

POST_ID, USER, DATE, MESSAGE

用户:

ID, SCREEN_NAME, IMAGE_URL

所以,每个帖子都有关联的 cmets,帖子和 cmets 都有关联的用户。优点是如果用户希望更改他们的屏幕名称或图像,只需更新用户表中的一行。但是,我不确定如何获取所有包含 X 标签的帖子,除非我有多个字段用于多个潜在标签?

或者,使用 MongoDB 之类的东西,我正在研究这样的格式:

帖子集合:

{ 
    {
    _ID: something
    USER: {id: id, name: "screen name", image: "image_url"}
    DATE: ...
    TITLE: ...
    TAGS: [tag1, tag2...]
    COMMENTS: 
         [
         {USER:someone, DATE:something, MESSAGE:"hi"},
         {USER:someone, DATE:something, MESSAGE:"another message"}
         ]
    },
    {
    _ID: something,
    USER: {id: id, name: "screen name", image: "image_url"},
    DATE: ...
    TITLE: ...
    TAGS: [tag1, tag2...]
    COMMENTS: 
         [
         ...
         ]
    },
}

因此,cmets 嵌入在每个帖子中,这看起来很自然。

在这里,一个查询可以检索我所有匹配的帖子,这很棒。另一方面,如果我需要更新用户使用的屏幕名称或图像怎么办?挖掘给定文档中的嵌入对象似乎很困难,更不用说更新每个帖子中的所有相关记录了。

我可以将 cmets 移动到一个单独的集合中以使其更易于访问,但我仍然面临着对屏幕名称等内容进行大量更新。

所以...

本质上,我更喜欢使用 MongoDB,因为它可以做的事情,它可以很容易地做,并且全面使用一种语言是很好的。但是,我不禁觉得我需要采用关系方法才能“正确”完成工作。

有没有人用任何一种语言或两种语言都做过类似的事情?

您对此有何看法,特别是您如何处理用户与 cmets/posts 之间的关系?

提前感谢您的帮助:) 詹姆斯

【问题讨论】:

  • 使用 Disqus 进行 cmets,使用 Jekyll 进行部署 - 10 分钟,您就完成了一个完全可维护的设置。

标签: mysql mongodb blogs


【解决方案1】:

这个问题绝对不归结为性能,因为 MongoDB 和 SQL 都会以完全相同的方式选择像这样的小型数据集,因此不会有真正可衡量的性能提升。

在这种情况下,MongoDB 的主要思想是能够将许多表嵌套在一个表中,从而减少查询来更新您的信息,例如,您只需查询一个表,而不是查询 12 个表。不仅如此,有时模式可能更符合您实际使用数据的方式。

我会更改您架构中的一些内容:

USER: {id: id, name: "screen name", image: "image_url"}

这应该只是一个与用户行相关的ObjectId,并再次在 cmets 中:

{USER:someone, DATE:something, MESSAGE:"hi"}

USER 字段使用ObjectId。这些ObjectIds 将与用户集合相关。还要去掉那些大写字母,我觉得写代码会很痛苦。

至于处理关系:- 您将可重复信息作为子文档嵌套到实体中(通常会在第 1 个 NF 中规范化),但这并不意味着您应该嵌套到无穷大,通常建议最多 3 级查询兼容性还考虑了应用实体的边界,例如blogpostuser

现在您必须管理非嵌套关系,例如 bloguser 行(因为帖子将嵌套 cmets 等)。解决这些关系的方法是客户端,因为 MongoDB 没有关系理想(它是 RDB 异端)。

您只需执行 MySQL 通常会在服务器端客户端执行的操作,即单独挑选用户,然后根据该用户 id 挑选帖子,而不是挑选出每一行的巨大结果集作为两者之间的连接user 和 post 表。

【讨论】:

  • 嗨,大写字母仅用于演示目的,以使其与我编写 mySQL 位的方式保持一致 :) 至于用户行;那很有意思。我特意嵌入了用户数据,以便减少查询;在其他地方拥有用户数据意味着查询为每个评论的用户检索图像/名称,这在我看来并不正确
  • @lytnus 嵌入此信息的问题在于它必须更新的方式。想象一个用户希望更改他们的用户名,这意味着您必须浏览所有帖子和/或 cmets 并更新该用户的用户名,这非常不可扩展。在这种情况下,用户行应该是分开的。所以这是另一种考虑是否应该嵌入某些东西的方式,至于它是否只与该项目有关,就像 cmets 只与帖子有关。
  • 谢谢;我认为我主要关心的是我必须提出的查询数量。我想这是一次交锋;您每次要查看 cmets 时都进行大量查询,但只更新用户信息的单个查询,或更新用户信息的大量查询但读取 cmets 的单个查询。如果阅读 cmets 的次数更多,我会认为倾向于嵌入式方法是值得的。不管怎样,我的心现在已经休息了,我将使用 MongoDB :)
  • @lytnus 是的,MongoDB 也是为读取繁重的场景而设计的,因此查询的数量并不重要,这是在执行 NoSQL 时丢弃 SQL 规则书的情况。事实上,游标本身直接从数据库流式传输,这与从写入内存或磁盘的特定结果集读取的 SQL 不同。因此,每次通过游标从数据库中获取新行时,实际上都是在数据库上重新运行该查询。
  • 太棒了,感谢您提供有用的信息!它也更容易上手和使用,所以我被征服了!
【解决方案2】:

我不同意需要使用关系方法才能正确完成工作。

决定取决于您是否可以免除 ACID 和关系细节。

如果您的博客是基于文档的,也许 NoSQL 方法可以正常工作。

更好的是,如果您使用 Java 或 C# 等面向对象的语言,您可以抽象出如何在接口后面持久化事物的细节,并将一个实现换成另一个实现。你不需要那样被锁住。

【讨论】:

  • 我想我的问题是真的,如果你放弃关系细节,你如何处理上述用户和帖子之间的关系,这样更新用户屏幕名称等操作可以在一个有效的方法?
  • NoSQL 更倾向于基于文档。如果您的用例不适合这种方法,那么您的决定就是为您做出的。
  • 如果你必须创建一个博客,并且与我的要求相似(非常基本的博客内容,真的),你会采用关系还是 NoSQL 方法?对您而言,例如,当用户更改他们的屏幕名称时必须更新大量内容的缺点是否会超过 NoSQL 方法带来的基于文档的更快访问的好处?你的架构会和我上面的不同吗?
  • 我不知道使用 NoSQL 访问文档会更快;你也没有。如果您将每个博客条目作为 CLOB 存储在关系数据库中,它与 NoSQL 并没有太大区别。
  • @lytnus 在获得超大型数据集之前,您不会真正了解性能差异。当拉一个小博客时,MySQL 和 NoSQL 的速度是一样的,因为它们都是以相同的方式拉的。这就是为什么这个问题没有真正的答案,因为它取决于你的喜好,它太主观了。
【解决方案3】:

我只会使用 wordpress,它非常受欢迎,而且我从来没有遇到过任何性能问题!当今全球 25% 的网站使用 wordpress!

【讨论】:

  • 我同意 wordpress 是一个不错的选择,我正在使用 node.js(不是 PHP)作为学习练习,所以这对我来说并不适用。
  • 多么好的解决方案?您是否甚至在评论之前阅读他发布的问题。题外回复。
猜你喜欢
  • 2016-05-31
  • 2022-01-22
  • 2019-06-17
  • 2013-12-30
  • 2016-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多