2

好的,我了解 NoSQL 数据库都是关于不使用关节进行查询的,但我根本无法理解某些概念。例如,假设我想要拥有多个作者和与作者相关的文章的博客,在 MySQL 中我会创建用户表:

Users: id, name, surname, nickname, password...
Articles: id, user_id, title, content, date, tags...

但我不确定在 MongoDB 中正确设置它的最佳方法是什么。我应该说:

db.users.insert({
    id:1,
    name: "Author name",
    ...
    articles: [{id:1, article:1, title:"Article title", ...}, {...}, ...]
});

我应该做这样的事情吗?:

db.articles.insert(
    {
    ...
    article related stuff
    ...
    user related stuff: {...}
);

或者也许我应该有单独的文章数据库和单独的用户数据库?

如果我的主页将显示 10 篇最新文章摘录以及作者数据,那么在 MySQL 中,我只需执行联合查询以从作者表中获取作者昵称,以及从文章表中获取标题和摘录。

我真的不确定如何在面向文档的数据库中表示我的数据。也许我应该在他的每篇文章中存储作者数据,但是如果作者更改了他的信息,则该作者的所有文章都需要更新。

在 MongoDB 中创建单独的文档对我来说似乎是合乎逻辑的。一个将保存所有作者文档,一个将保存所有文章文档,但这又需要某种联合操作,将获取前 10 篇文章并从作者文档中获取作者数据。

好的,也许是一些 map reduce 操作,但我不确定它会是什么样子。

感谢您对我的这个问题的想法和建议。谢谢!

[编辑]另外,如果我将所有文章保存在一个文档中,如果我是正确的,每个文档的限制为 16 mb,这在大型网站的情况下会出现问题,所以我想应该有单独的文章数据库?

4

2 回答 2

3

首先,让我更正您的一些术语:

  • db.databaseName.insert({是不正确的。连接到数据库后,将文档插入到集合中。该行应写为db.articles.insert({

  • 目前最大文档大小为16MB

在这种情况下,我可能会做的是将所有文章存储在文章集合中,其中一个字段是作者姓名(或作者昵称)。这样做的原因主要是因为您提到这是一个您将在主页上运行很多的查询。然后,您可以将其他作者信息存储在作者集合中的文档中。每个作者的 _id 字段可以只是作者姓名(或作者昵称)——它根本不需要是“ObjectId”类型,只要它是一个标量值(而不是数组)。

或者,您可以将作者的所有文章作为嵌套数组存储在文章集合中,就像您在第一个示例中展示的那样。16MB 的文档限制听起来可能有点小,但它比您想象的要多。例如,我博客上的 477 篇文章只占用 2.4MB。

于 2012-05-09T19:12:39.223 回答
3

正如@Pavel 已经提到的,我们假设您已经通过http://www.mongodb.org/display/DOCS/Schema+Design

模式设计在 MongoDB 中完全是一个相对概念,它会根据具体情况而定。您将如何设计集合,链接与嵌入实际上取决于您的数据架构、数据的大小以及您希望如何查询它。

如果您的作者信息没有占用太多空间,我会说在文章文档中嵌入作者信息是个好主意。查找速度会非常快,因为您可以在文章和作者上拥有索引(即使它们是嵌入的)。

当作者更改他的信息时,更新他/她的信息集合很容易。您只需要更新在其作者列表中列出该作者的文章。特别是通过使用 $(位置运算符)。http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

但是,如果您担心大小和限制,那就另当别论了。正如@Derick 提到的,16MB 很多,我的意思是很多。因此,如果您认为自己会达到极限,请选择单独的集合并进行链接。

据我所知,默认情况下 MongoDB 不提供跨多个集合的 MapReduce 功能,您最终可能会分几步完成,这将非常消耗资源。

MapReduce 不是非常适合生产使用。它最好由批处理过程使用,但对于实时聚合,您最好提出不同的解决方案(根据您的需求量身定制)并对其进行基准测试。有时在脚本端(Python、PHP 等)查找文档并进行聚合会更快。

作为最后一点,我只想说,无论 MongoDB 和 NoSQL 总体上多么漂亮、快速和时尚,但它们可能无法解决所有问题。一些问题最好通过传统的关系方法来解决。

于 2012-05-09T20:22:51.263 回答