本文是基于redis实现的热搜榜的解决方案,数据库方案可自行设计。不多说,直接上代码吧,仅供参考。若大家还有其他的方案,欢迎在评论区留言交流:bowtie:
下面列举一个使用有序集合实现的简单热搜榜示例:

  1. # zIncrBy keywords 1 key 集合keywords中成员'key'搜索次数+1
  2. redis 127.0.0.1:6379> zIncrBy keywords 1 php
  3. "1"
  4. redis 127.0.0.1:6379> zIncrBy keywords 1 mysql
  5. "1"
  6. redis 127.0.0.1:6379> zIncrBy keywords 1 python
  7. "1"
  8. redis 127.0.0.1:6379> zIncrBy keywords 1 golang
  9. "1"
  10. redis 127.0.0.1:6379> zIncrBy keywords 1 php
  11. "2"
  12. redis 127.0.0.1:6379> zIncrBy keywords 1 php
  13. "3"
  14. #从高到底返回集合内全部成员
  15. redis 127.0.0.1:6379> zRevRange keywords 0 -1
  16. 1) "php"
  17. 2) "python"
  18. 3) "mysql"
  19. 4) "golang"
  20. #从高到底返回集合内全部成员并显示搜索次数`score`
  21. redis 127.0.0.1:6379> zRevRange keywords 0 -1 withscores
  22. 1) "php"
  23. 2) "3"
  24. 3) "python"
  25. 4) "1"
  26. 5) "mysql"
  27. 6) "1"
  28. 7) "golang"
  29. 8) "1"

看了上面的例子是不是觉得很简单,一个简单的热搜榜就完成了。

php中基于redis的有序集合SortedSet实现热搜榜方法

下面列举了排行榜中几个可能用到的有序集合方法,注释仅供参考,可能描述不太准确。

  1. <?php
  2. /**
  3. * php redis SortedSet部分方法介绍
  4. * @author codehui admin@codehui.net
  5. * @link http://www.codehui.net
  6. * @data 2018-04-27
  7. */
  8. class Redisdemo{
  9. var $redis;
  10. public function __construct($host, $port, $auth = ''){
  11. $obj = new Redis();
  12. $connect = $obj->connect($host, $port);
  13. if($connect){
  14. if($auth){
  15. $obj->auth($auth);
  16. }
  17. $this->redis = $obj;
  18. }else{
  19. exit("redis connect fail:" . $connect);
  20. }
  21. }
  22. /*
  23. * 向有序集合添加一个或多个成员,或者更新已存在成员的score
  24. * @param string $key 集合名称
  25. * @param string $member 成员名称
  26. * @param int $score 值
  27. * return 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
  28. */
  29. public function zAdd($key, $score, $member){
  30. return $this->redis->zAdd($key, $score, $member);
  31. }
  32. /**
  33. * 返回有序集 key 中,指定区间内的成员。
  34. * @name zRange 递增排列
  35. * @name zRevRange 递减排列
  36. * @param string $key 集合名称
  37. * @param int $start 开始位置
  38. * @param int $end 结束位置 全部-1
  39. * @param boolean $withscores 返回成员score
  40. * @return array 集合列表
  41. */
  42. public function zRange($key, $start, $end, $withscores = null ) {
  43. return $this->redis->zRange( $key, $start, $end, $withscores);
  44. }
  45. public function zRevRange($key, $start, $end, $withscores = null ) {
  46. return $this->redis->zRevRange( $key, $start, $end, $withscores);
  47. }
  48. /**
  49. * 获取集合中成员的score
  50. * @param string $key 集合名称
  51. * @param string $member 成员名称
  52. * @return string key成员 member 的 score 值
  53. */
  54. public function zScore($key, $member) {
  55. return $this->redis->zScore( $key, $member );
  56. }
  57. /**
  58. * 关键词次数增量increment key不存在则自定ZADD
  59. * @param string $key 集合名称
  60. * @param int 增量
  61. * @param string $member 成员名称
  62. * @return string key成员 member 的新 score 值
  63. */
  64. public function zIncrBy($key, $increment, $member) {
  65. return $this->redis->zIncrBy($key, $increment, $member);
  66. }
  67. /**
  68. * 返回有序集合的key的基数
  69. * @param string $key 集合名称
  70. * @return int 有序集合的基数
  71. */
  72. public function zCard($key){
  73. return $this->redis->zCard($key);
  74. }
  75. }

使用方法

  1. // 初始化redis
  2. $redis = new Redisdemo('127.0.0.1', 6379);
  3. // 接收搜索关键词
  4. $keywords = $_REQUEST['k'];
  5. // 定义集合键名称
  6. $key = 'keywords';
  7. // 集合中添加关键词,指定score值为1 若关键词存在则更新score
  8. $redis->zAdd($key, 1, $keywords);
  9. // 集合中关键词搜索次数+1 若关键词不存在则自动ZADD
  10. $redis->zIncrBy($key, 1, $keywords);
  11. // 从低到高显示集合中的全部成员
  12. $redis->zRange($key, 0, -1);
  13. // 从高到底显示前三名并显示score值
  14. $redis->zRevRange($key, 0, 2, true);
  15. // 获取集合中成员'php'的score值
  16. $redis->zScore($key, 'php');
  17. // 获取集合中全部成员的数量
  18. $redis->zCard($key);