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数据结构来实现