2014-10-30 161 views
1

我很努力地为应用程序找到最好的数据库设计。我有一个SQL背景,倾向于创建一个或多或少的非规范化数据库设计。Mongo DB Schema Design

我有以下问题。我收集了大约2000篇文章的“文章”。每篇文章都有相当多的信息。实施推荐系统时,我想为每个“文章”将每个“用户”和“预测评分”关联起来。 在SQL中,我将使用三个表对这个模型进行建模:“文章”,“用户”,“UserToArticle”。 查询应该如下:我想为每个“Article”关联当前登录的用户的“PredictedRating”。在SQL中,我将通过“Article”和“Users”预先选择相应的用户。 拥有正确的索引非常快。

我怎么能用mongo的方式实现这个?当我用所描述的方式实现这个时,我不得不为每篇文章设置一个findOne()查询,这是非常低效和缓慢的(即使在使用索引时)。

你有什么想法吗?重要的是,只发布当前用户的预测评级。

+0

目前尚不清楚你需要什么类型的查询。例如,一个用户的所有评分或一篇文章的全部评分? – 2014-10-30 16:12:25

+0

好点:我需要一位用户的所有评级。 – Basil 2014-10-31 12:54:16

回答

2

规则拇指

的MongoDB的博客有一些good advice on data modeling

  1. 使用嵌入文档只要有可能。
  2. 如果一个子文档经常自己读取,最好不要嵌入它。
  3. 保持阵列小。如果嵌入的文档数组不断增长,请将其替换为参考ID数组。如果引用数组不断增长,请尝试反转引用或将引用提取到它自己的集合中。
  4. 应用程序级别的连接仍然是一个选项。正确使用索引和投影时,不应该有性能下降。
  5. 您可以嵌入很少更新但经常读取的文档,即使这意味着冗余数据。如果您需要频繁更新冗余数据,请不要嵌入冗余数据,因为这可能会超过读取优势。
  6. 针对您的应用优化您的数据模型。需要一起阅读或编写的内容应该更接近(更少的集合)。

因此,对文档数据库建模并不像标准化关系数据模型那么简单。当你掌握了这些经验法则时,你应该阅读about data models in the MongoDB manual


我们要放三个域对象到MongoDB的:用户文章已预测评级。我假设有很多用户和更多的文章。很明显,我们不应该把用户和文章放到一个集合中(子弹2,子集4和子集5)。因此,我们只需要决定放置预测评级的位置。

嵌入收视成篇

随着你的使用情况是获得一个用户的所有预测收视率,这将是适得其反把它们放进文章(6)。您需要搜索所有文章才能获得评分。除此之外,如果您删除用户,则需要更新每篇文章。

嵌入到收视用户

嵌入到收视用户的优点是,你只需要一个查询来获取用户和评级数据。但是你可能想为每篇文章给每个用户添加一个评级,因此这些数组将增长到很多(3)。

把收视率到它自己的收藏

因此它是可行的把收视率到自己的收藏。

{ 
    _id: ObjectId("f01..."), 
    userId: ObjectId("123..."), 
    articleId: ObjectId("abc..."), 
    predictedRating: 5.4 
} 

如上所述,这取决于您的数量结构。如果您的用户只有很少或文章很少,那么嵌入预测的评分可能是更简单快捷的解决方案。