Mongodb架构设计

时间:2014-10-30 14:15:38

标签: mongodb database-schema

我很难为应用找到最好的数据库设计。我有一个SQL背景,并倾向于创建一个或多或少非规范化的数据库设计。

我有以下问题。我收集了大约2000篇文章的“文章”。每篇文章都有很多信息。实现推荐系统,我希望将每个“用户”与每个“文章”的“PredictedRating”相关联。 在SQL中,我将使用三个表对其进行建模:“文章”,“用户”,“UserToArticle”。 查询应如下所示:我想为每个“Article”关联当前用户登录的“PredictedRating”。在SQL中,我将通过“Article”和“Users”联接来预选相应的用户。 拥有正确的索引非常快。

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

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

1 个答案:

答案 0 :(得分:2)

经验法则

MongoDB博客有一些good advice on data modeling

  1. 尽可能使用嵌入式文档。
  2. 如果一个子文档经常被自己阅读,最好不要嵌入它。
  3. 保持数组小。如果嵌入的文档阵列不断增长,请将其替换为参考ID数组。如果引用数组不断增长,请尝试反转引用或将引用提取到其自己的集合中。
  4. 应用程序级联接仍然是一种选择。正确使用索引和投影时,不应该有性能下降。
  5. 您可以嵌入很少更新但经常读取的文档,即使这意味着冗余数据。如果您需要经常更新冗余数据,请不要嵌入冗余数据,因为它可能会超过读取优势。
  6. 针对您的应用优化数据模型。需要一起阅读或书写的内容应该更靠近(更少的集合)。
  7. 因此,对文档数据库建模并不像规范化关系数据模型那样直接。掌握了这些经验法则后,您应该阅读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
    }
    

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