赞
踩
zset 是 set 的一个升级版本,它在 set 的基础上增加了一个顺序属性, 它和 set 一样,zset也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double类型的 score。 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 】
集合中最大的成员数为 2的(32 - 1)次方 (4294967295, 每个集合可存储40多亿个成员)。 zset 最经典的应用场景就是排行榜。
1、ZADD key score1 member1 score2 member2 score3 member3
将一个或多个member元素及其score值加入到有序集key当中。
2、ZRANGE KEY start end WITHSCORES
返回 [start,end] 这个区间的所有值
- 本地:0>zadd lxh 1 a 2 b 3 c 4 d 5 e
- "5"
-
- 本地:0>zrange lxh 0 -1
- 1) "a"
- 2) "b"
- 3) "c"
- 4) "d"
- 5) "e"
-
- 本地:0>zrange lxh 0 -1 withscores
- 1) "a"
- 2) "1"
- 3) "b"
- 4) "2"
- 5) "c"
- 6) "3"
- 7) "d"
- 8) "4"
- 9) "e"
- 10) "5"
-
- 本地:0>zrevrange lxh 0 -1
- 1) "e"
- 2) "d"
- 3) "c"
- 4) "b"
- 5) "a"
-
-
- 本地:0>zrevrange lxh 0 -1 withscores
- 1) "e"
- 2) "5"
- 3) "d"
- 4) "4"
- 5) "c"
- 6) "3"
- 7) "b"
- 8) "2"
- 9) "a"
- 10) "1"
3、zrem key member1 member2 ...
移除有序集key中的一个或多个成员,不存在的成员将被忽略。
- 本地:0>zrange lxh 0 -1 withscores
- 1) "a"
- 2) "1"
- 3) "b"
- 4) "2"
- 5) "c"
- 6) "3"
- 7) "d"
- 8) "4"
- 9) "e"
- 10) "5"
-
- 本地:0>zrem lxh a
- "1"
-
- 本地:0>zrange lxh 0 -1 withscores
- 1) "b"
- 2) "2"
- 3) "c"
- 4) "3"
- 5) "d"
- 6) "4"
- 7) "e"
- 8) "5"
4、zcard key
返回有序集key的基数。
- 本地:0>zrange lxh 0 -1 withscores
- 1) "b"
- 2) "2"
- 3) "c"
- 4) "3"
- 5) "d"
- 6) "4"
- 7) "e"
- 8) "5"
-
- 本地:0>zcard lxh
- "4"
5、zcount key min max
返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员。
- 本地:0>zrange lxh 0 -1 withscores
- 1) "b"
- 2) "2"
- 3) "c"
- 4) "3"
- 5) "d"
- 6) "4"
- 7) "e"
- 8) "5"
-
- 本地:0>zcount lxh 1 5
- "4"
-
- 本地:0>zcount lxh 2 3
- "2"
6、zscore key member
查找指定值,返回有序集key中,成员member的score值。
- 本地:0>zrange lxh 0 -1 withscores
- 1) "b"
- 2) "2"
- 3) "c"
- 4) "3"
- 5) "d"
- 6) "4"
- 7) "e"
- 8) "5"
-
- 本地:0>zscore lxh 2
- null
-
- 本地:0>zscore lxh b
- "2"
-
- 本地:0>zscore lxh e
- "5"
7、zincrby key increment member
为有序集key的成员member的score值加上增量increment。
- 本地:0>zrange lxh 0 -1 withscores
- 1) "b"
- 2) "2"
- 3) "c"
- 4) "3"
- 5) "d"
- 6) "4"
- 7) "e"
- 8) "5"
-
- 本地:0>zincrby lxh 10 b
- "12"
-
- 本地:0>zrange lxh 0 -1 withscores
- 1) "c"
- 2) "3"
- 3) "d"
- 4) "4"
- 5) "e"
- 6) "5"
- 7) "b"
- 8) "12"
8、zrevrange key start stop [WITHSCORES]
返回有序集key中,指定区间内的成员,降序。
zrange key start stop [WITHSCORES]
返回有序集key中,指定区间内的成员,升序。
- 本地:0>zrange lxh 0 -1 withscores
- 1) "c"
- 2) "3"
- 3) "d"
- 4) "4"
- 5) "e"
- 6) "5"
- 7) "b"
- 8) "12"
-
-
- 本地:0>zrevrange lxh 0 -1 withscores
- 1) "b"
- 2) "12"
- 3) "e"
- 4) "5"
- 5) "d"
- 6) "4"
- 7) "c"
- 8) "3"
9、zrangebyscore key min max limit offset count
返回指定集合【min ,max】区间的值,并进行分页-------返回值是升序排列
zrevrangebyscore key min max limit offset count
返回指定集合【min ,max】区间的值,并进行分页-------返回值是降序排列
- 本地:0>zrange lxh 0 -1 withscores
- 1) "c"
- 2) "3"
- 3) "d"
- 4) "4"
- 5) "e"
- 6) "5"
- 7) "b"
- 8) "12"
-
- 本地:0>zrangebyscore lxh 0 10 limit 0 10
- 1) "c"
- 2) "d"
- 3) "e"
-
- -- 降序排列的话, 就不是【min,max】 而是 【max,min】
- 本地:0>zrevrangebyscore lxh 0 10 limit 0 10
-
-
- 本地:0>zrevrange lxh 0 -1 withscores
- 1) "b"
- 2) "12"
- 3) "e"
- 4) "5"
- 5) "d"
- 6) "4"
- 7) "c"
- 8) "3"
-
-
- 本地:0>zrevrangebyscore lxh 10 0 limit 0 10
- 1) "e"
- 2) "d"
- 3) "c"
-
- -- 升序排列的话, 就不是【max,min】 而是 【min,max】
- 本地:0>zrangebyscore lxh 10 0 limit 0 10
-
10、zrank key member
查看这个member 在key集合里面排名(升序的排名)
- 本地:0>zrange lxh 0 -1 withscores
- 1) "c"
- 2) "3"
- 3) "d"
- 4) "4"
- 5) "e"
- 6) "5"
- 7) "b"
- 8) "12"
-
- -- 排序最开始值是 0开始的
- 本地:0>zrank lxh b
- "3"
zrevrank key member
查看这个member 在key集合里面排名(降序的排名)
- 本地:0>zrevrange lxh 0 -1 withscores
- 1) "b"
- 2) "12"
- 3) "e"
- 4) "5"
- 5) "d"
- 6) "4"
- 7) "c"
- 8) "3"
-
-
- 本地:0>zrevrank lxh b
- "0"
11、zremrangebyrank key start end
移除key集合里面【start,end】这个排名区间的值
- 本地:0>zrange lxh 0 -1 withscores
- 1) "c"
- 2) "3"
- 3) "d"
- 4) "4"
- 5) "e"
- 6) "5"
- 7) "b"
- 8) "12"
-
-
- 本地:0>zremrangebyrank lxh 0 1
- "2"
-
- 本地:0>zrange lxh 0 -1 withscores
- 1) "e"
- 2) "5"
- 3) "b"
- 4) "12"
12、zremrangebyscore key min max
移除key集合里面【min ,max】这个区间的值
- 本地:0>zadd lxh 1 a 2 b 3 c 10 d 100 e 500 f
- "6"
-
- 本地:0>zrange lxh 0 -1 withscores
- 1) "a"
- 2) "1"
- 3) "b"
- 4) "2"
- 5) "c"
- 6) "3"
- 7) "d"
- 8) "10"
- 9) "e"
- 10) "100"
- 11) "f"
- 12) "500"
-
- 本地:0>zremrangebyscore lxh 1 100
- "5"
-
- 本地:0>zrange lxh 0 -1 withscores
- 1) "f"
- 2) "500"
13、zinterstore key num key1 key2 key3
取key1,key2,key3的集合的交集放到key集合里面,由于需要取3个集合的交集,则num是3。返回值是交集的数量。也就是 key 集合的数量。
取交集的时候,会将相同的member的source值合并的。(求和)
- 本地:0>zrange lxh 0 -1 withscores
- 1) "a"
- 2) "1"
- 3) "b"
- 4) "2"
- 5) "f"
- 6) "500"
-
-
-
- 本地:0>zrange lxh1 0 -1 withscores
- 1) "a"
- 2) "1"
- 3) "b"
- 4) "2"
-
- 本地:0>ZINTERSTORE lxh2 2 lxh lxh1
- "2"
-
-
- 本地:0>zrange lxh2 0 -1 withscores
- 1) "a"
- 2) "2"
- 3) "b"
- 4) "4"
-
-
- zinterstore lxh3 3 lxh lxh1 lxh2
- "2"
-
-
14、zunionstore key key1 key2 key3
取key1,key2,key3的集合的并集放到key集合里面,,由于需要取3个集合的并集,则num是3。返回值是并集的数量,也就是 key 集合的数量。
取交集的时候,会将相同的member的source值合并的。(求和)
- 本地:0>zrange lxh 0 -1 withscores
- 1) "a"
- 2) "1"
- 3) "b"
- 4) "2"
- 5) "dd"
- 6) "25"
- 7) "f"
- 8) "500"
- 本地:0>zrange lxh2 0 -1 withscores
- 1) "a"
- 2) "2"
- 3) "b"
- 4) "4"
- 本地:0>zrange lxh1 0 -1 withscores
- 1) "a"
- 2) "1"
- 3) "b"
- 4) "2"
- 5) "dd"
- 6) "25"
- 本地:0>zunionstore lxh8 3 lxh lxh1 lxh2
- "4"
- 本地:0>zrange lxh8 0 -1 withscores
- 1) "a"
- 2) "4"
- 3) "b"
- 4) "8"
- 5) "dd"
- 6) "50"
- 7) "f"
- 8) "500"
需求一:完成热搜排行帮查询功能。
实现步骤:
1、当前毫秒数 / (1000*60*60) =时间块
2、获取得到每个热搜的时间块-----(时间块,热搜热度,热搜id),热搜热度 = 点赞+转发+阅读。
3、每隔1个小时,将从现在开始得到的时间块,和前23个小时时间块的24个集合取交集,将交集的结果给 到一个新集合,这个新集合就每日热搜的集合。
核心代码:
初始化数据+刷新数据
- package com.redis.zset;
- /*
- * 本类用来实现微博热搜
- *
- * 1、微博的榜单分为 小时榜,日榜,周榜,月榜
- * 2、我们现在需要做的是两件事情,一个是造出微博的数据
- * 3、查看指定榜单
- *
- *
- * */
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import javax.annotation.PostConstruct;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
- import java.util.Set;
- import java.util.concurrent.TimeUnit;
-
- @RestController
- @RequestMapping("WB")
- @Slf4j
- public class WBRedisController {
- private static final String REDIS_WB_HOUR = "redisWB_hour";
- private static final String REDIS_WB_DAY = "redisWB_day";
- private static final String REDIS_WB_WEEK = "redisWB_week";
- private static final String REDIS_WB_MONTH = "redisWB_month";
-
-
- @Autowired
- private RedisTemplate redisTemplate;
-
-
- @PostConstruct
- public void init() {
- new Thread(() -> {
- try {
- initWbData();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }).start();
- }
-
-
- @PostMapping("refreshWBData")
- public String getDayWBData() {
- // 每小时统计一次每天的数据
- refreshDayData();
- // 每小时统计一次每周的数据
- refreshWeekData();
- // 每小时统计一次每月的数据
- refreshMonthData();
- return "数据刷新成功";
- }
-
- private void initWbData() throws InterruptedException {
- // 由于没有热搜事件,通过26个字母来代替热搜事件,同时存储每个小时每个热搜(字母)的数据
- // 获取当前小时的时间块
- long key = System.currentTimeMillis() / (1000 * 60 * 60);
- // 获取当月的时间块,组装为key值
- for (int i = 0; i < 24 * 30; i++) {
- String redisKey = REDIS_WB_HOUR + (key - i);
- for (int j = 0; j < 26; j++) {
- int source = new Random().nextInt(10);
- // 添加的是 key , member,source(member这个属性对应的数值--double类型)
- redisTemplate.opsForZSet().add(redisKey, String.valueOf((char)(96+i)), source);
- }
- }
- log.info("" +
- "一个月内的数据初始化完成");
-
- // 开始定时刷新数据
- while (true) {
- // 每隔5秒钟开始刷新数据
- // 初始化数据完成之后,每隔5秒刷新一次数据,模拟用户的访问
- Thread.sleep(5000);
- refreshData();
- log.info("数据刷新成功");
- }
- }
-
- /*
- * 刷新数据----统计每小时的数据之和
- * 定时统计数据---每次要统计的单位是一个小时
- * */
- private void refreshDayData() {
- long key = System.currentTimeMillis() / (1000 * 60 * 60);
- List<String> list = new ArrayList<>();
- // 获取当天内的所有的集合
- for (int i = 0; i < 24; i++) {
- String redisKey = REDIS_WB_HOUR + (key - i);
- this.redisTemplate.expire(redisKey, 40, TimeUnit.DAYS);
- list.add(redisKey);
- }
- redisTemplate.opsForZSet().unionAndStore(null, list, REDIS_WB_DAY);
-
- }
-
-
- /*
- * 刷新数据----统计每周的数据之和
- *
- * */
- private void refreshWeekData() {
- long key = System.currentTimeMillis() / (1000 * 60 * 60);
- List<String> list = new ArrayList<>();
- // 获取当天内的所有的集合
- for (int i = 0; i < 168; i++) {
- String redisKey = REDIS_WB_HOUR + (key - i);
- list.add(redisKey);
- }
- redisTemplate.opsForZSet().unionAndStore(null, list, REDIS_WB_WEEK);
-
- }
-
-
- /*
- * 刷新数据----统计每月的数据之和
- *
- * */
- private void refreshMonthData() {
- long key = System.currentTimeMillis() / (1000 * 60 * 60);
- List<String> list = new ArrayList<>();
- // 获取当天内的所有的集合
- for (int i = 0; i < (24 * 30); i++) {
- String redisKey = REDIS_WB_HOUR + (key - i);
- list.add(redisKey);
- }
- redisTemplate.opsForZSet().unionAndStore(null, list, REDIS_WB_MONTH);
-
- }
-
-
- /*
- * 定时刷新数据---模拟用户的请求
- * */
- private void refreshData() throws InterruptedException {
- long key = System.currentTimeMillis() / (1000 * 60 * 60);
- for (int i = 0; i < 26; i++) {
- // 添加的是 key , member,source(member这个属性对应的数值--double类型)
- redisTemplate.opsForZSet().incrementScore(REDIS_WB_HOUR + key, String.valueOf((char)(96+i)), new Random().nextInt(5));
- }
- }
-
-
- }
获取排行榜数据信息
- package com.redis.zset;
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.Set;
-
- /*
- * 本类用来查询热搜排行榜的展示
- *
- * */
- @RestController
- @RequestMapping("WB")
- @Slf4j
- public class GetRdisWB {
-
- private static final String REDIS_WB_HOUR = "redisWB_hour";
- private static final String REDIS_WB_DAY = "redisWB_day";
- private static final String REDIS_WB_WEEK = "redisWB_week";
- private static final String REDIS_WB_MONTH = "redisWB_month";
-
-
- @Autowired
- private RedisTemplate redisTemplate;
-
- @PostMapping("getHourWBData")
- public Set getHourWBData() {
- long hour = System.currentTimeMillis() / (1000 * 60 * 60);
- Set set = redisTemplate.opsForZSet().rangeWithScores(REDIS_WB_HOUR+hour, 0, -1);
- return set;
-
-
- }
-
- @PostMapping("getDayWBData")
- public Set getDayWBData() {
- long hour = System.currentTimeMillis() / (1000 * 60 * 60);
- Set set = redisTemplate.opsForZSet().rangeWithScores(REDIS_WB_DAY, 0, -1);
- return set;
- }
-
- @PostMapping("getWeekWBData")
- public Set getWeekWBData() {
- long hour = System.currentTimeMillis() / (1000 * 60 * 60);
- Set set = redisTemplate.opsForZSet().rangeWithScores(REDIS_WB_WEEK, 0, -1);
- return set;
- }
-
- @PostMapping("getMonthWBData")
- public Set getMonthWBData() {
- long hour = System.currentTimeMillis() / (1000 * 60 * 60);
- Set set = redisTemplate.opsForZSet().rangeWithScores(REDIS_WB_MONTH, 0, -1);
- return set;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。