#第三条 尝试在单条查询中去获取数据(Try to fetch data in a single query)
在这条里面首先需要明白一个概念,叫做“应用单元(application unit)”。如果你开发的是一个Web应用或是移动应用,你可以将之理解为向后端发起的一次请求。另外一些例子,比如:
- 在桌面应用程序中,应用单元可能就是一次用户交互。
- 在分析系统中,应用单元也许就是一次图表的加载。
应用单元基本上就是指你应用程序中会进行数据库访问的离散单元。
MongoDB数据模型应该针对每个应用单元去做查询。
Example: a blog
假设我们正在设计一个博客程序,一次请求博客文章的过程应该是一个应用单元。当我们去显示一篇博文,需要的数据有博文内容、标签、作者的信息、以及博文的评论。因此,我们会将这些所有的信息都嵌入到博文文档(post document)中去,然后我们通过一次查询去获取所需的所有数据。
记住我们的目标是做一次查询,而不是在一个文档中查。有时候我们一次查询会返回多个文档或者文档的一部分(not evry field)。例如:主页可能需要从博文(post)文档集合中取最新的10篇博文,但只需要标题、作者、和摘要:
会有一个用来显示给定标签下面最新的20篇博文的页面:
还有有一个包含所有作者完整资料的作者集合(authors collection),作者页面很简单,仅仅是作者集合(authors collection)中的一个作者文档(author document):
博文集合(posts collection)中的的文档(document)也许会包含作者文档(author document)中的一些信息:作者名称和缩略图。
需要注意的是:尽管先前的例子中单次查询都是只与一个文档交互,这并不是说应用单元就应该只查询单个文档。事实上有许多情况应用单元需要通过单次查询来查询多个文档中的数据。
Example: an image board
假设我们有一个贴图板,用户可以在新的或是已经存在的线程中发布图片和文字。这个程序中有一个应用单元是在同一个线程中查看20条贴图信息,所以我们会将每个人的贴子(post)分别存储为帖子集合(posts collection)的文档。当我们需要显示的时候,会做如下查询:
当我们需要查看下一页的时候,我们做下面的查询:
然后我们会在{threadId:1,date:1}上面加索引,来提高查询效率。
当你的应用程序变得很复杂并且用户和经理又需要添加很多新特性的时候,请不要因为需要在一个应用单元中做多于一次的查询而感到沮丧.”one-query-per-unit”的目标是一个良好的起点和衡量初始设计是否合理的一个度量标准,现实的情况是很复杂的。在十分复杂的应用程序中,你可能会为其功能特性使用多于一条的查询。