从一个 table 获取待处理的好友请求

Get pending friend requests from one table

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

id user_id friend_id

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

(表示用户 1 向用户 2 发送了请求)

id user_id friend_id
1 1 2

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

已接受参考请求:

id user_id friend_id
1 1 2
2 2 1

我接受的查询如下所示(我使用书架 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,我似乎无法让它工作,所以如果有人知道答案或看到好的答案,请引导我,谢谢 :)。

qb.leftJoin('friends as friendsTwo', 'friends.user_id', 'friendsTwo.friend_id');
qb.whereNull('friendsTwo.user_id');

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

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

没有接受的友谊

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 字段进行更新。