从 String 到 Zset:Redis 核心数据结构全解析及排行榜应用

Redis底层的数据结构

常见的有5种类型:String、Hash、List、Set、Zset

|--------|-----------------|-----------------------------------------------|
| 类型 | 结构存储的值 | 结构的读写功能 |
| String | 字符串、整数、浮点型 | 对一整个字符串或部分字符串读取,浮点型可以自增或自减 |
| Hash | 散列键值对 | 添加、获取、删除单个元素 |
| List | 一个链表,链表的节点包含字符串 | 可以对链表两侧进行push和pop操作,根据值查找或删除元素,还可以读取多个元素 |
| Set | 无序存储字符串的集合 | 可以做集合的交、并、差集;获取、添加、删除元素 |
| Zset | 有序存储字符串的集合 | 有序集合,可以根据元素的不同分数排序,可以添加、获取、删除元素,可以根据分值范围来获得元素 |

应用场景:

String:缓存对象、常规计数、分布式锁、共享Session信息

Hash:缓存对象、购物车

List:消息队列(注意:1.生产者需要自行实现全局唯一ID;2.消费不能以消费组形式出现)

Set:聚合计算(并、差、交集)如共同关注、点赞、抽奖

Zset:需要排序的场景如排行榜

随着更新又出现了几个类型:GEO、HyperLoglog、Stream、BitMap

应用场景:

GEO:存储地图信息的场景,比如滴滴叫车

HyperLoglog:海量数据统计,比如百万计网页UV统计

Stream:消息队列,对比List而言,可以自行生成全局唯一ID;消费可以以消费组形式出现

BitMap:二值状态统计,比如签到

Zset使用,实现排行榜功能

就是对Zset的命令进一步熟悉,常见命令

SortedSet的常见命令有:

  • ZADD key score member:添加一个或多个元素到sorted set ,如果已经存在则更新其score值

  • ZREM key member:删除sorted set中的一个指定元素

  • ZSCORE key member : 获取sorted set中的指定元素的score值

  • ZRANK key member:获取sorted set 中的指定元素的排名

  • ZCARD key:获取sorted set中的元素个数

  • ZCOUNT key min max:统计score值在给定范围内的所有元素的个数

  • ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment值

  • ZRANGE key min max:按照score排序后,获取指定排名范围内的元素

  • ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素

  • ZDIFF.ZINTER.ZUNION:求差集.交集.并集

注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可,例如:

  • 升序获取sorted set 中的指定元素的排名:ZRANK key member

  • 降序获取sorted set 中的指定元素的排名:ZREVRANK key memeber

此处例子来自小林Coding

以博文点赞排名为例,小林发表了五篇博文,分别获得赞为 200、40、100、50、150。

java 复制代码
# arcticle:1 文章获得了200个赞
> ZADD user:xiaolin:ranking 200 arcticle:1
(integer) 1
# arcticle:2 文章获得了40个赞
> ZADD user:xiaolin:ranking 40 arcticle:2
(integer) 1
# arcticle:3 文章获得了100个赞
> ZADD user:xiaolin:ranking 100 arcticle:3
(integer) 1
# arcticle:4 文章获得了50个赞
> ZADD user:xiaolin:ranking 50 arcticle:4
(integer) 1
# arcticle:5 文章获得了150个赞
> ZADD user:xiaolin:ranking 150 arcticle:5
(integer) 1

实现点赞加一功能,使用ZINCREBY KEY SCORE MEMBER

如:

文章 arcticle:4 新增一个赞,可以使用 ZINCRBY 命令(为有序集合key中元素member的分值加上increment):

复制代码
> ZINCRBY user:xiaolin:ranking 1 arcticle:4
"51"

查看某篇文章的赞数,可以使用 ZSCORE KEY命令(返回有序集合key中元素个数):

复制代码
> ZSCORE user:xiaolin:ranking arcticle:4
"50"

获取小林文章赞数最多的 3 篇文章,可以使用 ZREVRANGE KEY 下标 命令(倒序获取有序集合 key 从start下标到stop下标的元素):

复制代码
# WITHSCORES 表示把 score 也显示出来
> ZREVRANGE user:xiaolin:ranking 0 2 WITHSCORES
1) "arcticle:1"
2) "200"
3) "arcticle:5"
4) "150"
5) "arcticle:3"
6) "100"

获取小林 100 赞到 200 赞的文章,可以使用 ZRANGEBYSCORE 命令(返回有序集合中指定分数区间内的成员,分数由低到高排序):

java 复制代码
> ZRANGEBYSCORE user:xiaolin:ranking 100 200 WITHSCORES
1) "arcticle:3"
2) "100"
3) "arcticle:5"
4) "150"
5) "arcticle:1"
6) "200"

Zset和set的区别是什么

Zset有序,且元素有对应分数,set无序

Zset: 有序,且元素唯一的集合,内容可以根据元素的分数排序,适合需要排序的场景如排行榜

添加元素(带分数):ZADD zset1 10 "a" 20 "b" 15 "c"(向 zset1 中添加元素,分数分别为 10、20、15)

按排名范围获取元素(从小到大):ZRANGE zset1 0 -1 WITHSCORES(返回所有元素及分数,结果按分数排序:"a" 10, "c" 15, "b" 20)

按分数范围获取元素:ZRANGEBYSCORE zset1 12 25(返回分数 12-25 之间的元素:"c", "b")

增减元素分数:ZINCRBY zset1 5 "a"(将 "a" 的分数 +5,变为 15)

获取元素排名:ZRANK zset1 "b"(返回 "b" 的排名,从 0 开始,此处返回 2)

Set:无序 ,**且元素唯一的集合,**适合存储内容无需排序且唯一的内容比如用户ID

添加元素:SADD set1 "a" "b" "c"(向 set1 中添加 3 个元素,重复添加会自动去重)

查看所有元素:SMEMBERS set1(返回结果无序,如 ["b", "a", "c"])

判断元素是否存在:SISMEMBER set1 "a"(存在返回 1,否则 0)

集合运算:SINTER set1 set2(求两个集合的交集)、SUNION set1 set2(求并集)

总之Zset比Set多了很多基于分数的操作,可以直接获取某个元素,也可以根据分数获取一定范围的元素,Set可以做集合运算比如交集并集差集等

Zset的底层是怎么实现的

Zset的底层是压缩列表或跳表实现的

若有序集合元素个数小于128并且每个元素的大小不超过64字节,则使用压缩列表

不满足以上条件则使用跳表

在redis7.0后压缩队列被废弃,改用了listpack数据结构来实现

相关推荐
世界尽头与你2 小时前
CVE-2025-55752_ Apache Tomcat 安全漏洞
java·安全·网络安全·渗透测试·tomcat·apache
Re.不晚2 小时前
Java进阶之路--线程最最详细讲解
java·开发语言
梵刹古音2 小时前
【C语言】 数组基础与地址运算
c语言·开发语言·算法
wuguan_2 小时前
C#/VP联合编程之绘制图像与保存
开发语言·c#
Howrun7772 小时前
C++_错误处理
开发语言·c++
遨游xyz2 小时前
数据结构-栈
java·数据结构·算法
海南java第二人2 小时前
Flink动态字符串处理框架:构建灵活可配置的实时数据管道
java·flink
lbb 小魔仙2 小时前
MyBatis-Plus 系统化实战:从基础 CRUD 到高级查询与性能优化
java·性能优化·mybatis
BLUcoding2 小时前
Docker 离线安装和镜像源配置
java·docker·eureka