在非关系数据库中存储喜欢

7 database non-relational-database mongoose mongodb nosql

要旨

我在我的应用程序中实现了一个喜欢按钮。假设用户能够喜欢其他用户的产品。

问题

我现在想知道以下哪种方法是将这些喜欢存储在非关系数据库(在我的例子中是 MongoDB)中最有效和最健壮的方法。重要的是,没有用户可以喜欢一个产品两次。

可能的解决方案

(1) 存储那些喜欢产品本身的用户 ID,并通过以下方式跟踪喜欢的数量 likes.length

// Product in database
    {
        likes: [
            'userId1',
            'userId2',
            'userId3',
            ...
        ],
        ...
    }
Run Code Online (Sandbox Code Playgroud)

(2) 存储用户自己喜欢的所有产品,并通过产品上的数字跟踪喜欢的数量

// User in database
{
    likedProducts: [
        'productId1',
        'productId2',
        'productId3',
        ...
    ]
    ...
}
// Product in database
{
    numberOfLikes: 42,
    ...
}
Run Code Online (Sandbox Code Playgroud)

(3)也许有更好的解决方案?

无论哪种方式,如果产品有很多喜欢或用户喜欢很多产品,则有大量数据,只需加载即可显示喜欢并检查用户是否已经喜欢它。

isp*_*zax 7

使用哪种方法,(1) 或 (2) 取决于您的用例,具体来说,您应该考虑需要更多访问哪些数据:检索特定用户喜欢的所有产品 (2) 或检索所有用户谁喜欢特定产品 (1)。看起来 (1) 是更常见的情况的可能性更大 - 这样您就可以轻松知道用户是否已经喜欢该产品以及该产品的喜欢数量,因为它只是数组长度。

我认为任何进一步的改进都可能是过早的优化 - 最好在手头有问题的情况下进行优化。

例如,如果显示喜欢的数量似乎是一个瓶颈,您可以通过将数组长度存储为单独的键值来进一步非规范化数据。这样显示产品列表就不需要从数据库中接收带有 userId 的点赞数组。

更不可能的是,对于单个产品的数百万个赞,您会发现循环遍历 likes 数组以检查 userId 是否已经在其中会显着减慢。当然,您可以使用排序数组之类的东西来保持喜欢排序,但数据库通信仍然很慢(无论如何都比在内存中循环数组慢)。最好使用数据库索引进行二进制搜索,而不是将喜欢的数组存储为嵌入到产品(或用户)中的数组,您可以将喜欢存储在单独的集合中:

{
    _id: $oid1,
    productId: $oid2,
    userId: $oid3
}
Run Code Online (Sandbox Code Playgroud)

假设产品具有多个喜欢的键,如果所有 3 个键都被索引,那应该是访问喜欢的最快方式。

您也可以发挥创意,将 $oid2+$oid3 串联为 $oid1,这将自动强制用户-产品对的唯一性。因此,您只需尝试保存它并忽略数据库错误(可能会导致细微的错误,因此在保存失败时检查是否存在会更安全)。


iaf*_*rek 5

为什么不直接修改需求并使用关系数据库或类似 RDBMS 的解决方案。基本上,使用正确的工具,完成正确的工作:

创建另一个表 Likes,将您的 ProductId 和 userId 对作为唯一键。例如:

userId1 - productId2
userId2 - productId3
userId2 - productId2
userId1 - productId5
userId3 - productId2
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过 userId 查询并获取每个用户的点赞数,或者通过 ProductId 查询并获取每个产品的点赞数。

而且,唯一键userId_productId将保证一个用户只能喜欢一种产品。

此外,您可以在另一列中保留额外信息,例如用户喜欢该产品的时间戳等。