好友推荐问题

原题和数据


  1. create table friend  
  2. (  
  3.     userid varchar(10),  
  4.     touserid varchar(10)  
  5. );  
  6.   
  7. insert into friend values('A','B');  
  8. insert into friend values('A','C');  
  9. insert into friend values('A','D');  
  10. insert into friend values('A','E');  
  11. insert into friend values('A','F');  
  12. insert into friend values('A','O');  
  13. insert into friend values('B','A');  
  14. insert into friend values('B','C');  
  15. insert into friend values('B','E');  
  16. insert into friend values('B','K');  
  17. insert into friend values('C','A');  
  18. insert into friend values('C','D');  
  19. insert into friend values('C','I');  
  20. insert into friend values('C','F');  
  21. insert into friend values('D','B');  
  22. insert into friend values('D','C');  
  23. insert into friend values('D','D');  
  24. insert into friend values('D','M');  
  25. insert into friend values('D','L');  
  26. insert into friend values('E','B');  
  27. insert into friend values('E','C');  
  28. insert into friend values('E','D');  
  29. insert into friend values('E','M');  
  30. insert into friend values('E','L');  
  31. insert into friend values('F','A');  
  32. insert into friend values('F','B');  
  33. insert into friend values('F','C');  
  34. insert into friend values('F','D');  
  35. insert into friend values('F','E');  
  36. insert into friend values('F','O');  
  37. insert into friend values('F','M');  
  38. insert into friend values('G','A');  
  39. insert into friend values('G','C');  
  40. insert into friend values('G','D');  
  41. insert into friend values('G','E');  
  42. insert into friend values('G','F');  
  43. insert into friend values('H','A');  
  44. insert into friend values('H','C');  
  45. insert into friend values('H','D');  
  46. insert into friend values('H','E');  
  47. insert into friend values('H','O');  
  48. insert into friend values('I','A');  
  49. insert into friend values('I','O');  
  50. insert into friend values('J','A');  
  51. insert into friend values('J','C');  
  52. insert into friend values('J','D');  
  53. insert into friend values('K','D');  
  54. insert into friend values('K','E');  
  55. insert into friend values('K','F');  
  56. insert into friend values('L','D');  
  57. insert into friend values('L','E');  
  58. insert into friend values('L','F');  
  59. insert into friend values('M','E');  
  60. insert into friend values('M','F');  
  61. insert into friend values('M','G');  
  62. insert into friend values('O','A');  
  63. insert into friend values('O','H');  
  64. insert into friend values('O','I');  
  65. insert into friend values('O','J');  

friend表,userid是好友关系发起方,touserid是好友关系接受方.



这个问题比较普遍
用数据库处理的优点:
1.面向集合的处理方式,可以一次生成所有用户的数据,作为一段时间的缓存.
2.方案简单

缺点:
时间比较长.一般作为夜间维护作业.如果数据量特别大,超过了夜维的窗口,就需要改方案.

需求一:找任意两个人的共同好友
  1. select t1.userid,t2.userid,count(*) from friend t1,friend t2  
  2. where   
  3. t1.userid!=t2.userid and   
  4. t1.touserid=t2.touserid   
  5. group by t1.userid,t2.userid  
  6. order by t1.userid,count(*) desc;  



使用笛卡尔积
t1表的好友等于t2表的好友,并且不等于自己
这个结果是 t1的userid和t2的userid有共同好友.

最后聚合,求出 t1.userid和t2.userid的共同好友数量.


需求二:推荐可能认识的人

关于需求二有两种实现方式:
第一种,在需求一的基础上,将t2.userid是t1.userid好友的记录过滤.
  1. select t3.* from (  
  2.     select t1.userid source_userid,t2.userid target_userid,count(*) c from friend t1,friend t2  
  3.     where   
  4.     t1.userid!=t2.userid and   
  5.     t1.touserid=t2.touserid   
  6.     group by t1.userid,t2.userid  
  7. ) t3 left join friend t4 on (t3.source_userid=t4.userid and t3.target_userid=t4.touserid)  
  8. where t4.userid is null  
  9. order by t3.source_userid,t3.c desc;



第二种实现,找到每个人所有好友的好友,如果不是他的好友,则推荐.
  1. select t3.* from (  
  2.     select t1.userid,t2.touserid,count(*)  c  
  3.     from   
  4.     friend t1 inner join friend t2 on(t1.touserid=t2.userid)  
  5.     where t1.userid!=t2.touserid   
  6.     group by t1.userid,t2.touserid  
  7. ) t3 left join friend t4 on (t3.userid=t4.userid and t4.touserid=t3.touserid)  
  8. where t4.userid is null  
  9. order by t3.userid,c desc;  


  where  t1.userid!=t2.touserid  
这句话是为了过滤已经建立好友关系的情况.
如果好友的好友,就是我自己,则过滤.




这两种实现,还是有差别的
第一种实现方式的语义是,若有人加过我的好友,但是没有加我,则推荐给我.
第二种实现方式的语义是,我好友加的好友,如果我没有加,则推荐给我

因为好友关系是双向的,单方面的请求,对方未必已经同意.
当然,可以进一步过滤,只保留建立了双向好友关系的记录,但是会进一步降低性能.似乎也没有这个必要.

从避免骚扰的角度考虑,选择第二种实现方式似乎较好.

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29254281/viewspace-1870745/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29254281/viewspace-1870745/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值