前言:
基础操作篇最后一环节,就是这个了! reids里面的有序集合...
向爬虫而生---Redis 基石篇4 <拓展Set>-CSDN博客
向爬虫而生---Redis 基石篇3 <拓展List>-CSDN博客
向爬虫而生---Redis 基石篇2 <拓展Hash>-CSDN博客
向爬虫而生---Redis 基石篇1 <拓展str>-CSDN博客
(前面的内容链接都放在这里了!)
正文
有序集合(Sorted Set)是Redis中的一个数据类型,它与普通集合(Set)的区别在于,有序集合的每个成员都关联着一个分数(score),使得成员可以根据分数进行排序。
特性介绍:
Redis的有序集合(Sorted Set)是一种功能强大的数据类型,它将成员与分数进行关联,并根据分数的排序顺序进行存储。有序集合可以进行高效的插入、删除和范围查询操作,非常适用于需要按照某个标准对元素进行排序和筛选的场景。有序集合的主要特点如下:
- 排序机制:有序集合中的成员按照分数进行排序,分数可以是浮点数或整数。
- 唯一性:通过成员的唯一性来保证集合中不会出现重复的元素。
- 灵活性:可以根据分数进行范围查询,获取特定范围内的元素。
- 快速访问:有序集合的底层实现采用跳表和哈希表的混合结构,可以实现快速的插入、删除和查找等操作。
基础操作:
有序集合(Sorted Set)是Redis中的一个数据类型,它与普通集合(Set)的区别在于,有序集合的每个成员都关联着一个分数(score),使得成员可以根据分数进行排序。以下是有序集合的相关命令和应用场景,以详细的讲解和案例进行说明。
-
zadd命令:
zadd key score value
该命令用于添加有序集合中的成员,并设置对应的分数。
-
zrem命令:
zrem key value
该命令用于从有序集合中删除指定的成员。
-
zcard命令:
zcard key
该命令用于计算有序集合中成员的数量。
-
zscore命令:
zscore key value
该命令用于获取指定成员的分数。
-
zincrby命令:
zincrby key X value
该命令用于根据给定的X值为指定成员的分数增加或减少。
-
zrank命令:
zrank key value
该命令用于获取指定成员在有序集合中的排名。
小扩展:
-
zrange key start end [withscores]
:- 此命令用于按照排名范围从有序集合中获取成员信息,可选择是否同时获取成员的分数(加上
withscores
选项)。 - 注意点:范围的起始和结束值都是基于有序集合的排名而不是分数。
127.0.0.1:6379> zadd leaderboard 100 "Player1" 130 "Player2" 80 "Player3" 150 "Player4" (integer) 4 127.0.0.1:6379> zrange leaderboard 0 2 withscores 1) "Player3"2) "80" 3) "Player1"4) "100"
使用
zadd
命令创建了一个名为leaderboard
的有序集合,包含了四个玩家和他们的分数。然后,我们使用zrange
命令获取排名前三的玩家信息以及他们的分数。 - 此命令用于按照排名范围从有序集合中获取成员信息,可选择是否同时获取成员的分数(加上
-
zrangebyscore key min max [withscores]
:- 此命令用于按照分数范围从有序集合中获取成员信息,可选择是否同时获取成员的分数。
- 注意点:范围的最小值和最大值都包含在内。
127.0.0.1:6379> zrangebyscore leaderboard 90 120 withscores 1) "Player1"2) "100"
使用
zrangebyscore
命令从leaderboard
有序集合中获取分数在90到120之间的成员,并获取他们的分数。 -
zcount key min max
:- 此命令用于计算有序集合中分数在指定范围内的成员数量。
127.0.0.1:6379> zcount leaderboard 100 150 (integer) 3
在上述示例中,我们使用
zcount
命令计算分数在100到150之间的成员数量。 -
zremrangebyrank key start end
:- 此命令用于按照排名范围从有序集合中删除成员。
127.0.0.1:6379> zremrangebyrank leaderboard 0 1 (integer) 2
使用
zremrangebyrank
命令删除leaderboard
有序集合中排名在0到1之间的成员。 -
zremrangebyscore key min max
:- 此命令用于按照分数范围从有序集合中删除成员。
127.0.0.1:6379> zremrangebyscore leaderboard 100 130 (integer) 2
使用
zremrangebyscore
命令删除leaderboard
有序集合中分数在100到130之间的成员。
在使用这些命令时,注意范围的起始和结束值以及是否包含边界,这将决定返回的成员集合和删除的成员数量。合理地使用这些命令将帮助您更好地操作和管理有序集合的成员。
应用:
案例1:
假设我们要创建一个文章排行榜,根据时间戳和点赞数对文章进行排名。我们可以使用Redis的有序集合来实现这个功能。
首先,假设我们有以下两篇文章:
- 文章A:时间戳为1635451200(2021年10月29日00:00:00),点赞数为500。
- 文章B:时间戳为1635364800(2021年10月28日00:00:00),点赞数为700。
我们可以使用以下命令将这些文章添加到有序集合中,并使用时间戳作为分数:
127.0.0.1:6379> ZADD articles:rankings 1635451200 "A"
(integer) 1
127.0.0.1:6379> ZADD articles:rankings 1635364800 "B"
(integer) 1
现在,我们可以通过以下命令获取排名前几的文章:
-
按时间降序排名:
127.0.0.1:6379> ZREVRANGE articles:rankings 0 -1 1) "A" 2) "B"
在上述示例中,我们使用
ZREVRANGE
命令获取按时间降序排名的两篇文章。由于有序集合默认按分数升序排列,我们使用ZREVRANGE
命令反向获取排名。 -
按点赞数降序排名:
127.0.0.1:6379> ZREVRANGE articles:rankings BYSCORE +inf -inf WITHSCORES 1) "B" 2) "700" 3) "A" 4) "500"
在上述示例中,我们使用
ZREVRANGE
命令按点赞数降序排名获取文章。我们使用BYSCORE +inf -inf
参数来表示获取所有成员,并包括分数。
通过这个例子,我们可以看到如何使用有序集合来实现文章排行榜功能。通过将文章的时间戳或点赞数作为分数,在有序集合中添加并根据分数进行排序,我们可以轻松地获取排名前几的文章。
案例2:
电商热销商品排行榜
假设我们有一个电商平台,我们希望根据商品的销量和评价来创建一个热销商品排行榜。我们可以使用有序集合来记录商品和其对应的销量和评价。
-
zadd
命令:zadd products:rankings sales_score product1
将商品销量和评价得分作为分数,使用
zadd
命令将商品及其销量和评价插入到有序集合中。 -
zincrby
命令:zincrby products:rankings 50 product1
使用
zincrby
命令增加商品的销量或评价得分。 -
zrange
命令:zrange products:rankings 0 4 withscores
使用
zrange
命令获取排名前五的热销商品和对应的销量或评价得分。 -
zrem
命令:zrem products:rankings product1
使用
zrem
命令从排行榜中删除指定的商品。
根据实际场景的需求,可能还会使用其他有序集合命令,例如zrevrange
用于按照分数或排名取出特定范围的商品,或使用zinterstore
和zunionstore
命令进行不同排行榜的交集和并集操作等。
通过使用这些命令,我们能够轻松地记录商品的销量和评价信息并根据分数进行排名和查询。这些功能可以帮助电商平台实时更新和展示热销商品信息,以提高用户体验和促进销售。
不常用的操作:
这里是对拓展命令的详细讲解和应用案例:
-
zrevrank
命令:zrevrank key member
返回有序集合中成员的逆序排名(从分数高到低)。- 逆序排名从0开始,即排名第一的成员返回0。
127.0.0.1:6379> zrevrank products:rankings product1 (integer) 2
使用
zrevrank
命令获取有序集合products:rankings
中product1
的逆序排名,结果为2。 -
zrevrange
命令:zrevrange key start stop [withscores]
返回有序集合中指定排名范围的成员,按照逆序排列。withscores
选项可选择是否同时返回成员的分数。
127.0.0.1:6379> zrevrange products:rankings 0 2 withscores 1) "product2"2) "400" 3) "product1"4) "300"
使用
zrevrange
命令获取有序集合products:rankings
中逆序排名前三的成员及其分数。 -
zrevrangebyscore
命令:zrevrangebyscore key max min [withscores]
根据逆序的分数范围,返回有序集合中的成员。withscores
选项可选择是否同时返回成员的分数。
127.0.0.1:6379> zrevrangebyscore products:rankings 500 200 withscores 1) "product2"2) "400" 3) "product1"4) "300"
使用
zrevrangebyscore
命令获取有序集合products:rankings
中逆序排名在分数范围500到200之间的成员及其分数。 -
zinterstore
命令:zinterstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
将多个有序集合的交集存储到新的有序集合中。numkeys
参数代表参与交集计算的有序集合的数量。
127.0.0.1:6379> zinterstore intersect:rankings 2 products:rankings sales:rankings WEIGHTS 1 0.5 (integer) 2
使用
zinterstore
命令计算了products:rankings
和sales:rankings
有序集合的交集,并将结果存储到intersect:rankings
有序集合中。WEIGHTS
选项用于设置计算交集时的权重。 -
zunionstore
命令:zunionstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
将多个有序集合的并集存储到新的有序集合中。numkeys
参数代表参与并集计算的有序集合的数量。
127.0.0.1:6379> zunionstore union:rankings 2 products:rankings sales:rankings WEIGHTS 1 0.5 (integer) 4
使用
zunionstore
命令计算了products:rankings
和sales:rankings
有序集合的并集,并将结果存储到union:rankings
有序集合中。WEIGHTS
选项用于设置计算并集时的权重。
通过使用这些拓展命令,我们可以进行更高级的操作,如获取逆序排名成员、通过逆序分数范围获取成员、计算交集和并集等。这些命令为我们提供了更大的灵活性来操作和处理有序集合的数据。
警告:
-
慎重使用范围查询:
- 范围查询(例如zrange、zrevrange、zrangebyscore等)是有序集合的常用操作之一,但在大型数据集或高并发环境下,范围查询可能会对性能产生一定影响。因此,在使用范围查询时应谨慎评估数据量和查询频率,确保性能满足需求。
-
用WITHSCO慎RES选项:
- 某些命令(例如zrange、zrangebyscore等)提供了返回成员的分数的选项WITHSCORES。尽管这对于某些应用场景很有用,但请注意在返回成员和分数时会占用更多的带宽和内存。因此,在使用WITHSCORES选项时,要确保有足够的资源来处理返回的额外数据。
-
警惕数据溢出:
- 由于Redis的有序集合使用的是浮点数作为分数,一些大范围或高度变化的分数可能会导致精度丢失或溢出。在设计和使用有序集合时,要注意分数的适用范围,以防止意外的数值问题。
-
内存消耗:
- 有序集合的底层数据结构相对复杂,在存储大量成员和分数时需要消耗一定的内存。在使用大型有序集合时,要确保服务器有足够的内存资源,并合理估算数据量的大小。
-
注意分数冲突:
- 如果多个成员具有相同的分数,Redis会根据成员的字典序进行排序。因此,在使用相同分数时,如果需要明确的排序顺序,请增加额外的标识或规则来进行区分。