MySQL关注与粉丝系统如何设计

clipboard.png
目前数据表设计成上图这个样子
假设表名是user_fans 用户A的用户id是1 用户B的用户id是2
用户A关注用户B 则插入数据时, 4个字段分别是 1 1 2 0
用户B关注用户A 则插入数据时, 4个字段分别是 2 2 1 0
此时他们是互粉状态 我将2条记录的status字段都由0改为1

用户A查看自己的粉丝列表 SQL则是 select fans_id, status from user_fans where user_id = 1
然后status字段可以用来判断用户A的粉丝和用户A的关系状态

但是这样存在一个问题就是 比如用户A查看用户B的粉丝列表
此时用户B的粉丝列表和用户A之间的关系就不好确定
只能先把用户A所有关注的用户id都查询出来, 然后遍历用户B的粉丝列表(假设查20个人出来, 遍历20长度的数组)
在foreach循环中判断20次用户B的粉丝的id是否在用户A的关注的数组中
数据量小的话应该不会有性能问题
但是比如用户A的关注了3000个人 那么查询出用户A关注的用户数组中就有3000个ID,
这样用户A每次查看他人的粉丝列表都会很慢, 引起性能问题, 请问有没有好的办法解决这样的问题?
看网上有的文章说粉丝与关注这样的系统应该使用redis, 如果用redis, 具体怎么使用, 用什么数据类型?

阅读 5.4k
3 个回答

你的思路反了,判断b粉丝列表中用户与a的关系的时候,仅判断当前页面的用户即可,不会先把a的所有关注找出来再去判断关系的
比方说当前在b粉丝列表第一页,有20条用户,只要检查这20个用户和a的关系即可,而不是把a的所有关注找出来,再去遍历b的粉丝列表判断关系


看了问题评论中的对话,再补充一下
1、对于一个正常的用户来说,关注数是不会无限制增大的,一般正常的在十到百的级别,多的在千级别
2、一般来说,对于用户主动关注的行为,会设置一个关注上限
在1和2的前提下,用户a的关注列表量级是可控而且不大的
3、查的时候,不是把a的粉丝列表都查出来,然后再去遍历20次,而是判断这20个用户在不在a的关注列表中,这两个是不一样的

但是这样存在一个问题就是 比如用户A查看用户B的粉丝列表
此时用户B的粉丝列表和用户A之间的关系就没有办法确定
只能先把用户A所有关注的用户id都查询出来, 然后遍历用户B的粉丝列表
在循环中判断用户B每个粉丝的id是否在用户A的关注的数组中
数据量小的话应该不会有性能问题
var $Afans = select fans_id from user_fans where user_id = A.id
var $AandBfans = select fans_id form user_fans where fans_id in ($Afans) and user_id = B.id

这样一段的查询,mysql还是能撑得住的

其次,用户A查看其他人的粉丝列表,异步加载其他人的粉丝列表中的人和A的关系,页面加载快,可以提升用户体验度。

第一, 假设真的有300000个粉丝, 那么查看b有多少个粉丝的时候, 妥妥的分页, 不会一次性查出所有; 分页带来的效率提升你懂的;
第二, 如同楼上所说, a看b的粉丝列表, 关注的只有b的粉丝是否互粉了a, 而不是b的粉丝是否互粉了a的粉丝, 这是1:n的关系不要弄成n:m的关系了;
第三, 三个字段都设成索引, 效率会更快, 不要小看了mysql innodb的性能哈哈哈

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题