《Redis核心原理与实战》学习笔记7——有序集合使用与内部实现原理

一、简介

有序集合类型 (Sorted Set) 相比于集合类型多了一个double类型的排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序值。

有序集合的存储元素值也是不能重复的,但分值是可以重复的。

二、基础使用

1、添加一个或多个元素

语法:zadd key score member [score member …]

127.0.0.1:6379> zadd zset1 10 java
(integer) 1
127.0.0.1:6379> zadd zset1 3 golang 4 sql 1 redis
(integer) 3

2、查询所有元素列表

语法:zrange key start stop

127.0.0.1:6379> zrange zset1 0 -1
1) "redis"
2) "golang"
3) "sql"
4) "java"

其中:-1表示最后一个元素。

3、查询有序集合的个数

语法:zcard key

127.0.0.1:6379> zcard rankset
(integer) 4

4、根据元素值删除一个或多个元素

语法:zrem key member [member …]

127.0.0.1:6379> zrem zset1 redis
(integer) 1

127.0.0.1:6379> zrange zset1 0 -1
1) "golang"
2) "sql"
3) "java"

说明:删除命令中如果包含了不存在的元素,不会影响命令的正常执行,不存在的元素将会被忽略,如下:

127.0.0.1:6379> zrem zset1 php sql
(integer) 1

5、查询某元素的 score 值

语法:zscore key member

127.0.0.1:6379> zadd zset1 2 php 15 rust 1 c++
(integer) 3

127.0.0.1:6379> zscore zset1 php
"2"

6、查询 score 区间内元素

语法:zrangebyscore key min max

127.0.0.1:6379> zrange zset1 0 -1
1) "c++"
2) "php"
3) "golang"
4) "java"
5) "rust"

127.0.0.1:6379> zrangebyscore zset1 5 10
1) "java"

7、查询 score 区间的元素的个数

语法:zcount key min max

127.0.0.1:6379> zcount zset1 5 10
(integer) 1

8、查询某元素排名

语法:zrank key member

# 新建zset集合,直览方便
zadd rankset 36372 USA 75083 India 6090 Russia 2917 Mexico 2957 Spain 3341 Iran
(integer) 6

127.0.0.1:6379> zrank rankset USA
(integer) 4

可以看出,排名是从 0 开始的,排名可以理解为元素排序后的下标值。

9、查询某元素倒序排名

语法:zrevrank key member

# 升序排序后的set集合如下:
2917 Mexico
2957 Spain
3341 Iran
6090 Russia
36372 USA
75083 India

127.0.0.1:6379> zrevrank rankset Iran
(integer) 3

10、根据排名删除元素

语法:zremrangebyrank key start stop

127.0.0.1:6379> zremrangebyrank rankset 0 2
(integer) 3

127.0.0.1:6379> zrange rankset 0 -1
1) "Russia"
2) "USA"
3) "India"

三、内部实现

有序集合是由 ziplist (压缩列表) 或 skiplist (跳跃表) 组成的。

  • 有序集合保存的元素个数要小于 128 个;
  • 有序集合保存的所有元素成员的长度都必须小于 64 字节。

当数据比较少时,满足以上两个条件中,有序集合将会使用ziplist存储;

若上述两个条件中的任意一个不能得到满足时,有序集合就会使用 skiplist 结构进行存储。

四、使用场景

  • 成绩排名;
  • 粉丝列表,根据关注的先后时间排序;
原文地址:https://www.cnblogs.com/luckyliulin/p/13713394.html