【问题标题】:MongoDB document schemaMongoDB 文档架构
【发布时间】:2012-01-05 23:01:03
【问题描述】:

我一直在开发一个带有 MongoDB 数据库层的 Web 项目。我有一个无法正确映射到文档数据库的特定实体,我认为最好获得一些反馈。

说,我有 User 和 Item 集合。用户可以喜欢或不喜欢项目。项目中也有标签,用户也可以喜欢或不喜欢标签。我需要能够足够快地查找喜欢/不喜欢计数。

我想出的是这样的(对于项目):

{
    name: "Item Name",
    statistics : {
        likes:      5,
        dislikes:   6
    },
    tags: [
        { name: "Foo", likes: 10, dislikes: 20 },
        { name: "Bar", likes: 5,  dislikes: 1  }
    ]
}

这是相当不错的。但问题是,我需要知道用户是否喜欢/不喜欢标签或商品。现在,我想出的是这样的:

{
    name: "Item Name",
    statistics : {
        likes:      5,
        dislikes:   6
    },
    tags: [
        { 
            name: "Foo", 
            likes: 2, 
            dislikes: 1,
            votes: [
                { user: "user1_id", vote: 1 }, //like 
                { user: "user2_id", vote: 1 }, //like 
                { user: "user3_id", vote: -1 }, //dislike 
            ]
        },
        { 
            name: "Bar", 
            likes: 0,  
            dislikes: 0,
            votes: []
        }
    ]
}

这看起来很有希望,我在这里看到的最大好处是,如果有人改变主意并且不喜欢他以前喜欢的东西,我可以进行原子更新。

但是,我预计每个项目中大约有 10 个标签,每个标签可能有 100 票。然后我为每个项目有大约 1000 个嵌套的投票对象。我知道 mongodb 可以处理 16mb 的文档,但仍然可以将这么多数据存储在一个文档中吗?

我应该选择标准化模型吗?也许有一个“tagvotes”集合和一个 itemvotes 集合?实际上对我来说感觉更自然。

如果我在思考关系性的还是理性的,只是在徘徊?

谢谢。

【问题讨论】:

    标签: c# mongodb data-modeling database


    【解决方案1】:

    可以在一个文档中存储这么多数据吗?

    我没有发现您为每个对象存储的数据数量存在问题,但您的读取/更新模式令人担忧:每次获取项目时,您也会获取所有选票, 每个用户的 id 等。另外,添加投票时,您将增长对象。有时,MongoDB 将不得不重新分配您的对象,这需要一些时间。随着时间的推移,它会了解到你是频繁增长的对象,填充因子会增加,但频繁增长的对象并不是最好的办法。

    如果有人改变主意并且不喜欢他以前喜欢的东西,我可以进行原子更新。

    这有点棘手。您可以使用$pull$push,但我不知道如何才能使likesdislikes 计数保持同步。此外,如果用户真的改变了主意,会发生什么?你必须同时做$push$pull,如果我没记错的话,这是不可能的。

    只是想知道我是在考虑关系还是理性?

    两者兼而有之。这是一个关系问题:-)

    现在我想得出结论,您应该对计数进行非规范化并将关系存储在不同的集合中,但 Hightechrider 已经写了。太慢了。 ;-)

    【讨论】:

      【解决方案2】:

      随着 M 和 N 的增长,在任何 M x N 类型的情况下,尝试嵌入一切都变得不可能。在你达到那个点之前,你需要创建一个单独的集合并进行客户端连接;但这并不意味着您必须将所有内容完全标准化。

      在这种情况下,请考虑您希望向用户展示哪些视图:显然您希望展示该项目、它有多少喜欢和不喜欢它以及已应用到它的标签集以及每个标签的受欢迎程度这些标签是。但是喜欢/不喜欢对象和喜欢/不喜欢每个标签的用户的实际列表可以进入单独的文档(在单独的集合中)。

      使用这样的架构,您可以执行一次查询来获取项目以及您需要在该项目旁边显示的所有内容。然后,如果您需要,只需再查询一次,即可获取当前用户对该项目的意见以及他们投票选择的与该项目相关的所有标签。

      【讨论】:

        猜你喜欢
        • 2016-02-29
        • 2020-09-12
        • 1970-01-01
        • 2016-07-24
        • 2018-08-23
        • 2020-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多