因开发需要加入粉丝关注模块.

在好友关注关系中,主要有以上三种状态,即:

我的粉丝(fans)
我的关注(follow)
互粉(mutual)

设计思路如下:

​总体思路我们采用redis里面的zset完成整个功能, 原因是zset有排序(我们要按照关注时间的倒序排列), 去重(我们不能多次关注同一用户)功能. 一个用户我们存贮两个集合, 一个是保存用户关注的人 另一个是保存关注用户的人.
具体命令参考:http://doc.redisfans.com/sorted_set/index.html
用到的命令是:
​ 1、 zadd 添加成员:命令格式: zadd key score member [score …]
​ 2、zrem 移除某个成员:命令格式: zrem key member [member ...]
​ 3、 zcard 统计集合内的成员数:命令格式: zcard key
​ 4、 zrange 查询集合内的成员:命令格式: ZRANGE key start stop [WITHSCORES]
​ 描述:返回指定区间的成员。其中成员位置按 score 值递增(从小到大)来排序。 WITHSCORES选项是用来让成员和它的score值一并返回.
​ 5、 zrevrange跟zrange作用相反
​ 6、zrank获取成员的排名:命令格式: zrank key member
​ 描述:返回有序集key中成员member的排名。成员按 score 值递增(从小到大)顺序排列。排名以0开始,也就是说score 值最小的为0。返回值:返回成员排名,member不存在返回nil.
​ 7、 zinterstore 取两个集合的交集:命令格式:ZINTERSTORE destination numkeys key key ...] [AGGREGATE SUM|MIN|MAX]
​ 描述:计算给定的一个或多个有序集的交集。其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。默认情况下,结果集中某个成员的 score 值是所有给定集下该成员 score 值之 和 。
返回值:保存到 destination 的结果集成员数。

Redis实现思路

1. 添加关注

添加关注分为两步:

将对方Bid添加到自己的关注A列表中;

Redis::ZADD("A:follow", time(), B)

将自己的Aid添加到对方B的粉丝列表中:

Redis::ZADD("B:fans", time(), A)

2. 取消关注

取消关注同样分为两步:

将对方Bid从自己A的关注A列表中移除;

Redis::ZREM("A:follow", B)

将自己的Aid从对方的粉丝B列表中移除:

Redis::ZREM("B:fans", A)

3. 关注列表

Redis::ZRANGE("A:follow", 0 , -1)

4. 粉丝列表

Redis::ZRANGE("A:fans", 0 , -1)

5. 人物关系

5.1、 单向关注
A单向关注B,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中没有B(或B的关注列表中没有A)。

Redis::ZSCORE("A:fans", B) #未返回分数

Redis::ZSCORE("A:follow", B) #返回分数

5.2、 是否互粉
A和B是否互粉,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中有B(或B的关注列表中有A)。同时成立才为互粉。

Redis::ZSCORE("A:fans", B) #返回分数

Redis::ZSCORE("A:follow", B) #返回分数

6. 数量相关

6.1、 关注数
Redis::ZCARD("A:follow"); #返回数量

6.2、 粉丝数
Redis::ZCARD("A:fans"); #返回数量

7. 排序取出所有的人

7.1、根据关注的时间倒叙取出用户的id

Redis::ZREVRANGE("A:fans", 0, -1, TRUE); #倒序取值

7.2、根据关注时间顺序取出用户的id

Redis::ZRANGE("A:fans", 0, -1, TRUE); #顺序取值

8.获取互粉列表Mutuals

Redis::SInter("A:follow","B:follow");

Redis::SInterStore("A_B:follow" , "A:follow","B:follow"); //选存储

Redis::ZRANGE("A_B:follow", 0 , -1)//再获取

具体功能实现 代码分为8个部分

public class RedisFollowHelper{//(FOLLOW_USERS)关注表private static string FOLLOW_USERS = "gz:{0}:follow";//(FANS_USERS)粉丝表private static string FANS_USERS = "gz:{0}:fans";private static string INFO_USERS = "uinfo:{0}";private static int INFO_USERS_TIME = 86400;/// <summary>/// 0.判断是否已经关注了/// </summary>/// <param name="cid"></param>/// <param name="followId"></param>/// <returns></returns>public static bool isFollowed(long cid, long followId){string followUsersKey = string.Format(FOLLOW_USERS, cid);object value = RedisHelper.ZScore(followUsersKey, followId);return value != null;}followId去关注别人,判断是否已关注//public static bool isFollowedByFollowId(long followId, User user)//{//    string fanUsersKey = string.Format(FANS_USERS, followId);//    Object value = RedisHelper.HGet(fanUsersKey, user.getId().ToString());//    return value != null;//}/// <summary>/// 1. 添加关注/// </summary>/// <param name="cid"></param>/// <param name="followId"></param>public static void follow(long cid, long followId){long dt = CFunc.GetTimeStamp(DateTime.Now);//1、将对方id添加到自己的关注列表中;string followUsersKey = string.Format(FOLLOW_USERS, cid);RedisHelper.ZAdd(followUsersKey, (dt, followId));//2、将自己的id添加到对方的粉丝列表中:string fanUsersKey = string.Format(FANS_USERS, followId);RedisHelper.ZAdd(fanUsersKey, (dt, cid));}/// <summary>/// 2. 取消关注/// </summary>/// <param name="cid"></param>/// <param name="followId"></param>public static void unFollow(long cid, long followId){//1、将对方id从自己的关注列表中移除;string followUsersKey = string.Format(FOLLOW_USERS, cid);RedisHelper.ZRem(followUsersKey, followId);//将自己的id从对方的粉丝列表中移除:string fanUsersKey = string.Format(FANS_USERS, followId);RedisHelper.ZRem(fanUsersKey, cid);}/// <summary>/// 3. 关注列表/// </summary>/// <param name="userId">查看者的用户id</param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] Follows(long userId, long start = 0, long stop = -1){string followsUsersKey = string.Format(FOLLOW_USERS, userId);string[] objectMap = RedisHelper.ZRange(followsUsersKey, start, stop);return objectMap;}/// <summary>/// 4. 粉丝列表/// </summary>/// <param name="followId"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] Fans(long userId, long start = 0, long stop = -1){string fansUsersKey = string.Format(FANS_USERS, userId);string[] objectMap = RedisHelper.ZRange(fansUsersKey, start, stop);return objectMap;}/// <summary>/// 5. 人物关系/// 1.cidA单向关注cidB/// </summary>/// <param name="cidA"></param>/// <param name="cidB"></param>public static bool LinkAtoB(long cidA, long cidB){string fanKey = string.Format(FANS_USERS, cidA);string followKey = string.Format(FOLLOW_USERS, cidA);//A单向关注B,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中没有B(或B的关注列表中没有A)。if (RedisHelper.ZScore(followKey, cidB) > 0 && RedisHelper.ZScore(fanKey, cidB) == null){return true;}return false;}/// <summary>/// 2.是否互粉/// </summary>/// <param name="cidA"></param>/// <param name="cidB"></param>/// <returns></returns>public static bool LinkAandB(long cidA, long cidB){string fanKey = string.Format(FANS_USERS, cidA);string followKey = string.Format(FOLLOW_USERS, cidA);//A和B是否互粉,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中有B(或B的关注列表中有A)。同时成立才为互粉。if (RedisHelper.ZScore(followKey, cidB) > 0 && RedisHelper.ZScore(fanKey, cidB) > 0){return true;}return false;}/// <summary>/// 6.1、 我的关注数/// </summary>/// <param name="userId"></param>/// <returns></returns>public static long FollowsCount(long userId){string followsCountKey = string.Format(FOLLOW_USERS, userId);long iCount = RedisHelper.ZCard(followsCountKey);return iCount;}/// <summary>/// 6.2、 我的粉丝数/// </summary>/// <param name="userId"></param>/// <returns></returns>public static long FansCount(long userId){string fansCountKey = string.Format(FANS_USERS, userId);long iCount = RedisHelper.ZCard(fansCountKey);return iCount;}/// <summary>/// 7.1根据粉丝添加的时间倒叙取出用户的id/// </summary>/// <param name="cid"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] FansByTimeDesc(long cid, long start = 0, long stop = -1){string fansCountKey = string.Format(FANS_USERS, cid);string[] objectMap = RedisHelper.ZRevRange(fansCountKey, start, stop);return objectMap;}/// <summary>/// 8.获取共同关注列表/// </summary>/// <param name="cidA"></param>/// <param name="cidB"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] Mutuals(long cidA, long cidB, long start = 0, long stop = -1){string followsUsersA = string.Format(FOLLOW_USERS, cidA);string followsUsersB = string.Format(FOLLOW_USERS, cidB);string[] objectMap = RedisHelper.SInter(followsUsersA, followsUsersB);//也可以使用RedisHelper.SInterStore,存储起来再查询if (stop > start){long iCount = objectMap.Length;if (start <= iCount){if (stop > iCount){stop = iCount;}int j = 0;string[] newMap = new string[] { };for (long i = start; i < stop; i++){newMap[j] = objectMap[i];j++;}return newMap;}}return objectMap;}/// <summary>/// 7.2根据关注的时间倒叙取出用户的id/// </summary>/// <param name="cid"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] FollowByTimeAsc(long cid, long start = 0, long stop = -1){string fansCountKey = string.Format(FOLLOW_USERS, cid);string[] objectMap = RedisHelper.ZRevRange(fansCountKey, start, stop);return objectMap;}public static JObject getUserInfo(long cid, bool Refresh = false){string UsersKey = string.Format(INFO_USERS, cid);string userstr = "";if (Refresh == false){//是否强制刷新数据userstr = RedisHelper.Get(UsersKey);}JObject jo = new JObject();if (string.IsNullOrEmpty(userstr)){//查询数据库数据DataSet ds = ;if (ds.Tables[0].Rows.Count > 0){jo.Add("cid", cid);jo.Add("nickname", CFunc.SafeToStr(ds.Tables[0].Rows[0]["nickname"]));jo.Add("headpic", 1);// CFunc.ObjToInt32(ds.Tables[0].Rows[0]["regtime"]);jo.Add("xkpic", 1);// CFunc.ObjToInt32(ds.Tables[0].Rows[0]["logindate"]);RedisHelper.Set(UsersKey, jo, INFO_USERS_TIME);}ds.Clear();}else{jo = (JObject)JsonConvert.DeserializeObject(userstr);RedisHelper.Expire(UsersKey, INFO_USERS_TIME);}return jo;}internal static bool infoChanged(long cid){string UsersKey = string.Format(INFO_USERS, cid);if (RedisHelper.Exists(UsersKey)){RedisHelper.Del(UsersKey);return true;}return false;}}

C# 使用Redis实现粉丝好友互粉数据存储和查询相关推荐

  1. MapReduce—案例(六)求互粉好友对

    题目: A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D,E,F H:A,C,D,E,O ...

  2. MapReduce案例5——求互粉好友对

    题目: A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D,E,F H:A,C,D,E,O ...

  3. 微博粉丝互粉列表统计

    微博粉丝互粉统计 mapper阶段 import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.io.Text; import ...

  4. python+beautifulsoup/xpath实现新浪微博某互粉好友全部好友圈微博爬虫

    主要是懒,想要翻刚刚互粉的好友的全部好友圈微博,然而懒得一个一个去翻,就做了这个. 所谓一切机械性重复工作都可以交给计算机去做,就是我了我这种懒人而生的吧--

  5. 求好友中互粉的好友对

    好友列表: A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D,E,F H:A,C,D,E, ...

  6. 自媒体如何快速涨粉?除了互粉还有这3个方法,能轻松上手

    自媒体时代,涨粉成了每个自媒体作者关心的问题.自媒体平台虽然流量大.推荐量也多,但是收益却不是很理想,如果想要月入过万,最好的办法就是涨粉,毕竟粉丝收益还是不错的. 经常有小伙伴遇到这样的问题,为什么 ...

  7. 计蒜客第七章:互粉攻略

    计蒜客习题:互粉攻略 题目 样例 思路 邻接矩阵,mp[0][j]记录粉丝数,mp[i][1]记录关注数,注意重复输入过滤. 代码 #include<iostream> using nam ...

  8. php微博互粉网站源代码,PHP联合【新浪微博】实现第三方登陆

    获取 APP KEY和 APP SECRET 第一步:请求用户授权的token [appkey]&redirect_uri=[回调地址]&response_type=code 请求参数 ...

  9. Redis实战之好友关注功能

    目录 1.关注和取消关注 2.好友关注 - 共同关注 3.好友关注 - Feed 流实现方案 4.好友关注 - 推送到粉丝收件箱 1)传统了分页在 feed 流是不适用的,因为我们的数据会随时发生变化 ...

最新文章

  1. python发挥_充分发挥 Python 的威力:用最简单的方法打造互联互通的智能产品
  2. Nuke编辑工具包新版 Cara VR 插件发布
  3. 记录 之 cat 和 awk gsub 的使用
  4. 三足鼎立 —— GPM 到底是什么?(一)
  5. lamp mysql开机自启_centos下设置自启动和配置环境变量的方法
  6. hikari数据源配置类_Spring中的“多数据源”之详解
  7. Blazor.Server以正确的方式集成Ids4
  8. 导航器 Navigator
  9. 文本框仅可接收decimal
  10. c# hdf5 写string_Pandas系列之入门篇——HDF5
  11. “互联网+”时代,漫谈影响用户体验的X因素
  12. 微PE制作U盘启动盘图文详细教程
  13. fastadmin 邮件配置
  14. 4.7开发者日:北极光创投吴峰的投资只管杀不管埋
  15. 核心业务8:提现+展示还款信息和回款信息
  16. python爬虫爬取豆瓣电影信息城市_Python爬虫入门 | 2 爬取豆瓣电影信息
  17. linux刷新分区表,linux磁盘分区的详细步骤(图解linux分区命令使用方法)
  18. hadoop、hive安装
  19. 如何在页面上呈现谷歌地图
  20. 【毕业设计】深度学习实现行人重识别 - python opencv yolo Reid

热门文章

  1. 下载open jdk 和阿里Alibaba Dragonwell (开源open JDK)
  2. [深度学习]CNN的基础结构与核心思想
  3. 前端框架介绍篇(小白专属)
  4. 上顿号符号_顿号在键盘上怎么打 常见的电脑符号输入方法说明
  5. VMware Workstation 不可恢复错误: (vmx)Exception 0xc0000006 (disk error while paging) has occurred.
  6. 正则表达式高级学习技巧
  7. VS修改项目解决方案名称
  8. win10锁屏壁纸保存方法
  9. 记录解决nonebot2中定时器报时区问题的错误
  10. java布道师_我和 Spring 技术布道师的一天