热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

GistIimplementedalikebuttoninmyapplication.Letsimagineusersareabletolikeotheruser

Gist

I implemented a like button in my application. Let's imagine users are able to like other users products.

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

Issue

I am now wondering which of the following is the most effective and robust method to store those likes in a non-relational Database (in my case MongoDB). It's important that no user can like a product twice.

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

Possible Solutions

(1) Store the user ids of those, who liked on the product itself and keep track of the number of likes via likes.length

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

// Product in database
    {
        likes: [
            'userId1',
            'userId2',
            'userId3',
            ...
        ],
        ...
    }

(2) Store all products, that a user liked on the user itself and keep track of the number of likes through a number on the product

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

// User in database
{
    likedProducts: [
        'productId1',
        'productId2',
        'productId3',
        ...
    ]
    ...
}
// Product in database
{
    numberOfLikes: 42,
    ...
}

(3) Maybe there is even a better solution for this?

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

Either way, if the product has many likes or the user liked many products, there is a big amount of data, that has to load only to show likes and check if the user has already liked it.

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

2 个解决方案

#1


1  

Which approach to use, (1) or (2) depends on your use case, specifically, you should think about what data you will need to access more: to retrieve all products liked by a particular user (2) or to retrieve all users who liked a particular product (1). It looks more likely that (1) is a more frequent case - that way you would easily know if the user already liked the product as well as number of likes for the product as it is simply array length.

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

I would argue that any further improvement would likely be a premature optimization - it's better to optimize with a problem in hand.

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

If showing number of likes, for example, appears to be a bottleneck, you can denormalize your data further by storing array length as a separate key-value. That way displaying the product list wouldn't require receiving array of likes with userIds from the database.

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

Even more unlikely, with millions of likes of a single product, you'll find significant slowdown from looping through the likes array to check if the userId is already in it. You can, of course, use something like a sorted array to keep likes sorted, but database communication would be still slow (slower than looping through array in memory anyway). It's better to use the database indexing for binary search and instead of storing array of likes as array embedded into the product (or user) you can store likes in a separate collection:

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

{
    _id: $oid1,
    productId: $oid2,
    userId: $oid3
}

That, assuming, that the product has key with a number of likes, should be fastest way of accessing likes if all 3 keys are indexed.

假设产品具有许多喜欢的密钥,那么如果所有3个密钥都被编入索引,则应该是访问喜欢的最快方式。

You can also be creative and use concatenation of $oid2+$oid3 as $oid1 which would automatically enforce uniqueness of the user-product pair likes. So you'd just try saving it and ignore database error (might lead to subtle bugs, so it'd be safer to check like exists on a failure to save).

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

#2


3  

Why simply not amend requirements and use either relational database or RDBMS alike solution. Basically, use the right tool, for the right job:

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

Create another table Likes that keeps pair of your productId and userId as unique key. For example:

创建另一个表喜欢将productId和userId配对作为唯一键。例如:

userId1 - productId2
userId2 - productId3
userId2 - productId2
userId1 - productId5
userId3 - productId2

Then you can query by userId and get number of likes per user or query by productId and get number of likes per product.

然后,您可以通过userId查询并获取每个用户的喜欢数量或按productId查询,并获得每个产品的喜欢数量。

Moreover, unique key userId_productId will guarantee that one user can only like one product.

此外,唯一密钥userId_productId将保证一个用户只能喜欢一个产品。

Additionally, you can keep in another column(s) extra information like timestamp when user liked the product etc.

此外,当用户喜欢产品等时,您可以在其他列中保留额外信息,例如时间戳等。


推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • Postgresql备份和恢复的方法及命令行操作步骤
    本文介绍了使用Postgresql进行备份和恢复的方法及命令行操作步骤。通过使用pg_dump命令进行备份,pg_restore命令进行恢复,并设置-h localhost选项,可以完成数据的备份和恢复操作。此外,本文还提供了参考链接以获取更多详细信息。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • Excel数据处理中的七个查询匹配函数详解
    本文介绍了Excel数据处理中的七个查询匹配函数,以vlookup函数为例进行了详细讲解。通过示例和语法解释,说明了vlookup函数的用法和参数的含义,帮助读者更好地理解和运用查询匹配函数进行数据处理。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
author-avatar
Hyukjae333
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有