从一张桌子获取待处理的好友请求

Posted

技术标签:

【中文标题】从一张桌子获取待处理的好友请求【英文标题】:Get pending friend requests from one table 【发布时间】:2021-08-21 17:25:16 【问题描述】:

我正在尝试从具有架构的表中获取所有待处理的好友请求:

id user_id friend_id

待处理的请求只是一行,例如:

(意思是用户1向用户2发送了请求)

id user_id friend_id
1 1 2

当被接受时,它变成两行,我可以加入这个表中的两个来找到所有接受的(这工作得很好)。

已接受的参考请求:

id user_id friend_id
1 1 2
2 2 1

我接受的查询如下所示(我使用的是 bookshelf js 和 knex.js):

const friends = new Friends();
    return friends.query((qb) => 
        qb.select('friends.user_id', 'friends.friend_id');
        qb.join('friends as friendsTwo', 'friends.user_id', 'friendsTwo.friend_id');
        qb.where('friends.user_id', '=', id);
    ).fetchAll();

如何修改它以仅获得单向关系? 我的第一个想法是 leftJoin,但我似乎无法让它工作,所以如果有人知道答案或看到了一个好的答案,请引导我,谢谢:)。

【问题讨论】:

这与node.jsbookshelf.js无关,请编辑您的问题以删除不相关的标签。 这种在数据库中为单个好友请求创建条目的方法是一种讨厌的方法。您应该创建另一个名为is_accepted 的列,其中包含好友请求的状态。这样,每当发送新朋友请求时,您都会创建一个条目,并在接受请求时更新相同的条目。尽可能改进数据库结构,否则一旦部署到生产环境,当您拥有更大的数据集时就会出现问题。 【参考方案1】:

我认为你可以完全放弃加入这个项目的想法。我在之前的项目中做过类似的事情,我认为最好添加第三个字段isMutual,意思是它们是否是相互的。该字段是不言自明的,并认为您明白了。之后你的桌子必须看起来像

没有接受的友谊

id user_id friend_id isMutual
1 1 2 false

接受友谊

id user_id friend_id isMutual
1 2 1 true
2 1 2 true

我相信这样做实际上会使您的系统受益,因为您的查询会更快并尝试创建compound index for (user_id, friend_id)。这种解决方案更倾向于转移负载。

结论

使用它,您可以实现更快的查询,但是在以前的架构中 READ OPERATION 期间完成的所有艰苦工作都将转移到 WRITE OPERATION。 但我认为这会进一步降低写入速度。 是的,请确保您使用事务对 isMutual 字段进行更新。

【讨论】:

好吧,这种方法甚至可以进一步改进,只需为特定的好友请求创建一条记录,并且每次接受请求时,只需在另一个名为 is_accepted 的列上放置一个布尔值。我真的不明白为什么要为一个朋友请求输入两个条目。这只会将冗余数据存储在数据库中。 我是为复合索引做的。我同意**这只会将冗余数据存储在数据库中**。但我认为注销第二个条目会使查询SLOWER READ 变得困难。因为使用像 SELECT COUNT(*) FROM TABLE WHERE user_id=1 OR friend_id=1 这样的查询会增加读取操作的成本。 ** 作为基于 Postgres 的开发人员说 @MatBailie 使用我建议的方法,您可以使用WHERE user_id=X AND is_accepted=0 查询待处理的请求。我不确定您之前的评论到底是什么意思?为什么要为同一个好友请求维护两个条目? 哦,我明白了。我认为当 Instagram 类型的模型有追随者时,我的效果最好。但是您的评论应该涵盖我实施中的一些弱点。您的想法应该在像 facebook 这样的朋友系统中运行良好。 Learned something new. Thankyou @Salvino - 你质疑为什么要保持两条记录。我给出了一个场景,系统查询一个特定用户的所有朋友。如果我请求与 Nirjal 成为朋友,并且被接受,我的 id 在user_id 列中。但是,如果您请求与我成为朋友并且被接受,我的 ID 在 friend_id 列中。这意味着要获得我朋友的完整列表,我需要查询 WHERE friend_id = Mat OR user_id = Mat 两列,即扫描而不是搜索。保持两个方向意味着只需要查询一列。相当于双向链表等【参考方案2】:
qb.leftJoin('friends as friendsTwo', 'friends.user_id', 'friendsTwo.friend_id');
qb.whereNull('friendsTwo.user_id');

这将LEFT JOIN,保留所有行(待处理或接受),但随后过滤以仅保留friendsTwo 中没有匹配记录的行;因此只返回待处理的链接。

【讨论】:

以上是关于从一张桌子获取待处理的好友请求的主要内容,如果未能解决你的问题,请参考以下文章

获取直到前一个日期的待处理票积压计数

对 Firebase 的待处理请求的可能原因是啥?

如何让待处理状态自动显示?

我怎样才能将它从一张桌子存储到另一张桌子?

第二篇:白话tornado源码之待请求阶段

为啥 Chrome 或 Firefox 不显示待处理请求的请求标头?