Redis实现好友关注 共同关注 关注推送

Redis实现好友关注

关注与取关

数据库设计

创建数据库表,保存关注信息

create table follow
(
    id          int auto_increment
    primary key,
    userID      int null comment '用户id',
    followID    int                                 null comment '博主id',
    idDeleted   int       default 0                 null,
    createdTime timestamp default CURRENT_TIMESTAMP null,
    constraint id
    unique (id)
);

查询关注状态

public Boolean getFollow(Long followId) {
    String phone = UserHolder.getUser().getPhone();
    User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", phone));
    Integer userID = user.getId();
    return followMapper.exists(
        new QueryWrapper<Follow>().eq("followID", followId).eq("userID", userID)
    );
}

关注与取关

public Boolean setFollow(Long id) {
    String phone = UserHolder.getUser().getPhone();
    User user = userMapper
        .selectOne(new QueryWrapper<User>().eq("phone", phone));
    Integer userID = user.getId();
    boolean isFollowed = followMapper.exists(
        new QueryWrapper<Follow>()
        .eq("followID", id).eq("userID", userID)
    );
    if (isFollowed) {
        // 取关
        followMapper.delete(new QueryWrapper<Follow>()
                            .eq("followID", id).eq("userID", userID));
        return false;
    }
    // 关注
    Follow f = new Follow();
    f.setUserID(userID);
    f.setFollowID(Math.toIntExact(id));
    followMapper.insert(f);
    return true;
}

共同关注

优化关注

关注过程中,在redis维护一个set集合存放关注列表。通过set取交集的方式查询共同关注。

public Boolean setFollow(Long id) {
    String phone = UserHolder.getUser().getPhone();
    User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", phone));
    Integer userID = user.getId();
    boolean isFollowed = followMapper.exists(
        new QueryWrapper<Follow>().eq("followID", id).eq("userID", userID)
    );
    if (isFollowed) {
        // 取关
        followMapper.delete(new QueryWrapper<Follow>().eq("followID", id).eq("userID", userID));
        redisTemplate.opsForSet().remove("RedisSessionDemo:follow:" + userID, String.valueOf(id));
        return false;
    }
    // 关注
    Follow f = new Follow();
    f.setUserID(userID);
    f.setFollowID(Math.toIntExact(id));
    followMapper.insert(f);
    redisTemplate.opsForSet().add("RedisSessionDemo:follow:" + userID, String.valueOf(id));
    return true;
}

共同关注

public List<UserDTO> getCommonFollow(Long followID) {
    String phone = UserHolder.getUser().getPhone();
    User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", phone));
    Integer userID = user.getId();
    Set<String> commonIds = redisTemplate.opsForSet().intersect("RedisSessionDemo:follow:" + userID, "RedisSessionDemo:follow:" + followID);
    if (commonIds == null) {
        return null;
    }
    List<User> commonUser = userMapper.selectBatchIds(commonIds);
    ArrayList<UserDTO> results = new ArrayList<>();
    commonUser.forEach(u -> results.add(BeanUtil.copyProperties(u, UserDTO.class)));
    return results;
}

关注推送

Feed流

关注推送也叫做Feed流,直译为投喂。为用户持续的提供“沉浸式”的体验,通过无限下拉刷新获取新的信息。

Feed流实现方案

拉模式

拉模式:也叫做读扩散。

image-20240215232926781

推模式

推模式:也叫做写扩散。

image-20240215232956590

推拉结合模式

推拉结合模式:也叫做读写混合,兼具推和拉两种模式的优点。

image-20240215233032063

实现方式对比
拉模式推模式推拉结合
写比例
读比例
用户读取延迟
实现难度复杂简单很复杂
使用场景很少使用用户量少、没有大V过千万的用户量,有大V
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wmh1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值