你熟悉redis吗?
你熟悉redis每种类型的使用场景吗?
redis作为一个目前最流行的nosql数据库,在众多大小公司都有广泛的应用。
redis支持五种基本的类型,string,hash,list,set及zset(sorted set)。每种类型都有自己使用的场景。
今天就来看看sorted set的常见用法,
sorted set和set类似,都是一个数据的集合,sorted set是set的升级版本,每个元素都有一个关联的score,整个set就是根据score进行排序的。
如: 用set构建一个用户组
127.0.0.1:6379> smembers user1) "lily"2) "vincent"3) "jim"4) "ted"
用sorted set构建一个用户组,用户的分数作为score
127.0.0.1:6379> zrange score 0 -1 WITHSCORES1) "lily"2) "80"3) "jim"4) "88"5) "vincent"6) "90"7) "ted"8) "95"
利用sorted set这种有序的特性,非常适合排序、排行、榜单这些场景!
默认sorted set是按照score的值从小到大排序的,如果需要倒序,可以使用zrevrange命令。
如今很多的资讯网站都有一个热搜榜的功能,如图:
百度热搜榜
微博热搜榜
像这种统计性的数据,一般不会实时从数据库读取的,基础数据放到MySQL,统计结果基本都是放到cache,然后定时更新。
今天我们就用redis 的 sorted set来实现类似热搜榜的功能。
以下伪代码是我用php写的,实现了数据增加、修改、删除、获取top N的几个常用功能,如果你需要其他功能,可以自己扩展
<?phpclass Top{var $redis;var $key = 'weibo_hot';/** * redis的初始化 * @Author vincent yang * @DateTime 2020-11-26 */public function __construct(){$this->redis = new Redis();$this->redis->connect('localhost', 6379);$this->redis->auth('123456');}/** * 获取top榜,从高到低 * @Author vincent yang * @DateTime 2020-11-26 * @param integer $n 个数 * @return [type] [description] */public function getTop($n = 10, $withScore = true){$rs = $this->redis->zrevrange($this->key, 0, $n, $withScore);return $rs;}/** * 增加或更新值,对$value不存在的值会新增,存在的值会更新 * @Author vincent yang * @DateTime 2020-11-26 * @param [type] $value [description] * @param [type] $score [description] * @return [type] [description] */public function updateData($value, $score){$this->redis->zadd($this->key, $score, $value);}/** * 删除元素 * @Author vincent yang * @DateTime 2020-11-26 * @param [type] $value [description] * @return [type] [description] */public function removeByValue($value){$this->redis->zrem($this->key, $value);}}$obj = new Top();$rs = $obj->getTop(10);print_r($rs);$obj->updateData('Title01', 500);?>~
效率:
sorted set的增删改效率都很高,时间复杂度为
O(M*log(N)), N 为有序集的基数, M 为被成功操作的成员的数量。
因为是有序的集合,所以访问任意位置的数据速度都很快。
最后:
解决问题的方法有很多,你是怎么实现这种功能呢,欢迎交流!