好的,我理解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篇文章并从作者文档中获取作者数据。
好吧,也许有些地图减少了操作,但我不确定它会是什么样子。
我很感激你的想法,并对我的这个问题提出建议。谢谢!
[编辑] 另外,如果我在一个文档中保存所有文章,如果我是正确的,每个文档的限制为16 MB,如果是大型网站,这将是一个问题,所以我想应该有单独的文章数据库?
答案 0 :(得分:3)
首先,让我更正你的一些术语:
db.databaseName.insert({
不正确。连接到数据库后,将文档插入集合。该行应写为db.articles.insert({
。
目前最大文件大小 16MB 。
在这种情况下我可能会做的是将所有文章存储在文章集合中,其中一个字段是作者姓名(或作者尼克)。原因主要是因为您提到这是一个您将在主页上运行很多的查询。然后,您可以在 authors 集合中的文档中存储其他作者信息。每个作者的_id字段可能只是作者姓名(或作者姓名) - 它不需要属于" ObjectId&# 34;完全,只要它是标量值(而不是数组)。
或者,您可以将作者的所有文章作为嵌套数组存储在文章集合中,就像您在第一个示例中所示。一个16MB的文档限制可能听起来有点像,但它比你想象的要多。例如,我博客上的477篇文章只占用2.4MB。
答案 1 :(得分: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,但它们可能不是所有问题的答案。 传统的关系方法可以最好地解决一些问题。