Redis支持数据类型详解

4 数据类型

Redis支持多种数据类型:string(字符串),hash(哈希),list(列表),set(集合)、zset(sorted set 有序集合)、HyperLogLog (基数统计)、streams(流)、geospatial(地理空间)、bitmaps(位图)。

这里我们只列举了五大常用数据类型。

4.1 String

  • string是Redis中最常用的一种数据类型,也是Redis中最简单的一种数据类型。
  • string 表面上它是字符串,但其实他可以灵活的表示字符串、整数、浮点数3种值。Redis会自动的识别这3种值。
  • string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象 。
  • string 类型是一个键最大能存储 512MB。

SET-添加

用来设置指定 key 的值。语法如下:

SET key value

实例:

127.0.0.1:6379> set name hello
OK
127.0.0.1:6379> get name
"hello"

GET-获取

获取指定 key 的值。语法如下:

GET key

实例:

127.0.0.1:6379> set name hello
OK
127.0.0.1:6379> get name
"hello"

EXISTS-判空

判断指定key的值是否存在,语法如下:

EXISTS key

实例:

# name存在
127.0.0.1:6379> exists name
(integer) 1
# age存在
127.0.0.1:6379> exists age
(integer) 1
# sex不存在
127.0.0.1:6379> exists sex
(integer) 0
# 判断多个,有两个存在
127.0.0.1:6379> exists name age sex
(integer) 2

SETNX-不存在时添加

只有在 key 不存在时设置 key 的值。语法如下:

SETNX key value

实例:

127.0.0.1:6379> set key1 hello
OK
# 因为 key1 已经存在,设置失败
127.0.0.1:6379> setnx key1 world
(integer) 0
# 因为 key2 不存在,设置成功
127.0.0.1:6379> setnx key2 world
(integer) 1
# 查看 key1 和 key2 的内容
127.0.0.1:6379> mget key1 key2
1) "hello"
2) "world"

MSET-添加多个

同时设置一个或多个 key-value 对,如果有存在的值会被覆盖。语法如下:

MSET key value [key value ...]

实例:

127.0.0.1:6379> mset mykey1 value1 mykey2 value2 mykey3 value3
OK
127.0.0.1:6379> mget mykey1 mykey2 mykey3
1) "value1"
2) "value2"
3) "value3"

MSETNX-添加多个

同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。语法如下:

MSETNX key value [key value ...]

实例:

127.0.0.1:6379> set mykey1 hello
OK
127.0.0.1:6379> set mykey2 world 
OK
127.0.0.1:6379> msetnx mykey1 value1 mykey2 value2 mykey3 value3
(integer) 0
127.0.0.1:6379> mget mykey1 mykey2 mykey3
1) "hello"
2) "world"
3) (nil)

MGET-获取多个

获取所有(一个或多个)给定 key 的值。语法如下:

MGET key1 [key2..]

实例:

127.0.0.1:6379> set name1 hello
OK
127.0.0.1:6379> set name2 world
OK
127.0.0.1:6379> mget name1 name2
1) "hello"
2) "world"

GETSET-替换

将给定 key 的值设为 value ,并返回 key 的旧值(old value)。语法如下:

GETSET key value

实例:

127.0.0.1:6379> set name admin
OK
127.0.0.1:6379> getset name administrator
"admin"

GETBIT-获取位值

对 key 所储存的字符串值,获取指定偏移量上的位(bit)。语法如下:

GETBIT key offset

实例:

# 字符串 a 的二进制为 01100001
127.0.0.1:6379> set name a
OK
# 获取第一个bit位
127.0.0.1:6379> getbit name 0
(integer) 0
# 获取第二个bit位
127.0.0.1:6379> getbit name 1
(integer) 1

SETBIT-设置位值

对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。语法如下:

SETBIT key offset value

实例:

# 字符串 a 的二进制为 01100001
127.0.0.1:6379> set name a
OK
# 将字符串 a 的第二个bit设置为0,即 00100001
127.0.0.1:6379> setbit name 1 0
(integer) 1
127.0.0.1:6379> get name
"A"

SETRANGE-替换部分

用 value 参数替换给定 key 所储存的字符串值,从下标 offset 开始。语法如下:

SETRANGE key offset value

实例:

127.0.0.1:6379> set mykey administrator
OK
# 将xxxx替换掉mykey中的内容,从下标5开始
127.0.0.1:6379> setrange mykey 5 xxxxx
(integer) 13
127.0.0.1:6379> get mykey
"adminxxxxxtor"

STRLEN-获取长度

返回 key 所储存的字符串值的长度。语法如下:

STRLEN key

实例:

127.0.0.1:6379> set mykey administrator
OK
127.0.0.1:6379> strlen mykey
(integer) 13

GETRANGE-获取部分

返回 key 中字符串值的子字符。语法如下:

GETRANGE key start end

实例:

127.0.0.1:6379> set name administrator
OK
127.0.0.1:6379> getrange name 0 5
"admini"# 注意包含尾下标

SETEX-设置过期

设置value值的时候,同时设定过期时间 (以秒为单位)。语法如下:

SETEX key seconds value

实例:

# 设置 name 的过期时间为 120 秒
127.0.0.1:6379> setex name 15 "hello world"
OK
127.0.0.1:6379> get name
"hello world"
127.0.0.1:6379> ttl name
(integer) 13

PSETEX-设置过期

这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间。语法如下:

PSETEX key milliseconds value

实例:

127.0.0.1:6379> psetex mykey 100000 
"hello world"
OK
127.0.0.1:6379> get mykey
"hello world"

APPEND-追加

如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。语法如下:

APPEND key value

实例:

127.0.0.1:6379> get mykey 
"hello world"
127.0.0.1:6379> append mykey ". administrator"
(integer) 26
127.0.0.1:6379> get mykey
"hello world. administrator"

INCR-自增

将 key 中储存的数字值增一,只针对字面量是数字的。语法如下:

INCR key

实例:

127.0.0.1:6379> set count 1
OK
127.0.0.1:6379> incr count 
(integer) 2
127.0.0.1:6379> get count "2"

INCRBY-加法

将 key 所储存的值加上给定的增量值(increment),只针对字面量是数字的 。语法如下:

INCRBY key increment

实例:

127.0.0.1:6379> set count 1
OK
127.0.0.1:6379> incrby count 10
(integer) 11
127.0.0.1:6379> get count "11"

INCRBYFLOAT-加法

将 key 所储存的值加上给定的浮点增量值(increment),只针对字面量是数字的 。语法如下:

INCRBYFLOAT key increment

实例:

127.0.0.1:6379> set salary 100.5
OK
127.0.0.1:6379> incrbyfloat salary 2.4
"102.9"
127.0.0.1:6379> get salary
"102.9"

DECR命令-减法

将 key 中储存的数字值减一,只针对字面量是数字的。语法如下:

DECR key

实例:

127.0.0.1:6379> set count 100
OK
127.0.0.1:6379> decr count
(integer) 99
127.0.0.1:6379> get count
"99"

DECRBY命令-减法

key 所储存的值减去给定的减量值(decrement),只针对字面量是数字的 。语法如下:

DECRBY key decrement

实例:

127.0.0.1:6379> set count 100
OK
127.0.0.1:6379> decrby count 20
(integer) 80
127.0.0.1:6379> get count
"80"

SCAN-迭代

遍历当前库中key,语法如下:

SCAN cursor [MATCH pattern]
# cursor 游标索引
# pattern 匹配规则

在这里插入图片描述
在这里插入图片描述

中文显示问题

redis是支持存储中文的,但存储完获取查看时,会显示中文的utf-8字符编码
在这里插入图片描述

可以在打开redis会话时,使用如下命令打开

redis-cli --raw
# 将数据强制原始输出

在这里插入图片描述

4.2 Hash

Redis 哈希数据类型(hash)是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

Redis 中每个 hash 可以存储 2^32 - 1 个键值对(40多亿)。

4.2.1 Hash命令

这里的命令主要是针对Hash对象中的字段操作,创建如下对象对其操作

127.0.0.1:6379> hset user:10 id 10 name jack age 20 sex man
(integer) 4
# 根据key删除哈希表中的age和sex字段
hdel user:10 age sex# 根据key判断哈希表某个字段是否存在
hexists user:10 age# 根据key获取哈希表的某个字段值
hget user:10 name# 根据key获取哈希表的所有字段和值
hgetall user:10# 根据key获取哈希表的所有字段名
hkeys user:10# 根据key获取哈希表的所有值
hvals user:10# 哈希表 key 中的指定字段的整数值加上增量 (increment)
hincrby user:10 age 5# 为哈希表 key 中的指定字段的浮点数值加上增量 (increment)
hincrbyfloat user:10 id 10.5# 获取哈希表中字段的数量
hlen user:10# 设置哈希表字段,如果key代表哈希表存在,就追加内容。不存在就创建
hset user:10 address CN hobby music# 获取哈希表中多个字段的值
hmget user:10 id name# 当哈希表中字段不存在时,才能设置
hsetnx user:10 name lion# 迭代遍历哈希表中的key,并展示key和value
hscan user:10 0 match *a*

4.2.2 使用实例

1)将用户基本信息采用哈希数据结构保存,如下:

# 保存用户数据到hash
127.0.0.1:6379> hset user:100 id 100 name lion age 30
(integer) 3# 获取用户数据hash中的name字段
127.0.0.1:6379> hget user:100 name
"lion"# 获取用户数据hash中的所有数据
127.0.0.1:6379> hgetall user:100
1) "id"
2) "100"
3) "name"
4) "lion"
5) "age"
6) "30"

(2)使用 hash 作为计数器,计数设备 “777” 的ping服务器、发出请求、发送错误的次数。如下:

# 添加一台设备777
127.0.0.1:6379> hset device:777 pings 0 errors 0 requests 0
(integer) 3
# 模拟 777 设备 ping 三次
127.0.0.1:6379> hincrby device:777 pings 1
(integer) 1
127.0.0.1:6379> hincrby device:777 pings 1
(integer) 2
127.0.0.1:6379> hincrby device:777 pings 1
(integer) 3# 模拟 777 设备错误一次
127.0.0.1:6379> hincrby device:777 errors 1
(integer) 1# 模拟 777 设备请求一次
127.0.0.1:6379> hincrby device:777:stats requests 1
(integer) 1# 获取 777 设备的 ping 次数
127.0.0.1:6379> hget device:777 pings
"3"# 获取 777 设备请求和错误次数
127.0.0.1:6379> hmget device:777 requests errors
1) "1"
2) "1"

4.3 List

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

一个列表最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过 40 亿个元素)。

Redis列表通常用于:

  • 实现堆栈和队列。
  • 为后台工作系统构建队列管理。

注意:当消耗完列表中的信息后,这个列表就失效了。

4.3.1 List命令

操作list时,要时刻记住,这是一个类似管道的字符串列表,有左(头)右(尾)之分。

因此多个命令是成对出现的,分别操作它的头尾。

同时,内部的字符串被消耗完之后,这个列表就失效了。

查看列表信息
# 查看列表长度【元素个数】
llen mylist# 查看列表指定范围内的元素,如果写 0 -1 代表查看所有元素
lrange mylist 0 4
添加元素

如果列表不存在会创建一个

语法:

# 头部插入一个或多个
LPUSH key value1 [value2]
# 尾部插入一个或多个
RPUSH key value1 [value2]

示例

127.0.0.1:6379> lpush mylist1 100
(integer) 1
127.0.0.1:6379> lpush mylist1 200 300 400
(integer) 4
# 400 300 200 100127.0.0.1:6379> rpush mylist2 100
(integer) 1
127.0.0.1:6379> rpush mylist2 200 300 400
(integer) 4
# 100 200 300 400# push多个元素时,按照从左到右,一个一个压入。
# 因此要注意头尾顺序,不要想当然的认为,就是编写命令时的顺序。

列表不存在会添加失败,返回0

语法:

# 头部添加
LPUSHX key value
# 尾部添加
RPUSHX key value

通过索引添加元素

语法:

LSET key index value

示例:

127.0.0.1:6379> lpush list2 aa bb cc dd
(integer) 4
127.0.0.1:6379> lset list2 2 xx
OK
127.0.0.1:6379> lrange list2 0 -1
1) "dd"
2) "cc"
3) "xx"
4) "aa"

在列表中某个元素的前或后插入元素,如果列表中有相同的元素,只会对最左侧的生效

语法:

LINSERT key BEFORE|AFTER pivot value
# 该命令没有对应右侧插入的

示例

127.0.0.1:6379> lpush msg 111 222 333
(integer) 3
127.0.0.1:6379> llen msg
(integer) 3
127.0.0.1:6379> linsert msg before 222 999
(integer) 4
127.0.0.1:6379> lrange msg 0 -1
1) "333"
2) "999"
3) "222"
4) "111"
提取元素
# 从列表头部(左侧)提取一个元素
lpop mylist# 从列表尾部(右侧)提取一个元素
rpop mylist# 移除列表的尾元素,并将该元素添加到另一个列表头部
rpoplpush list1 list2
# 这个命令没有对应的另一个
提取元素等待

只提取

从列表中提取一个元素,如果有则立即取出,如果列表是空的会等待后面设定的秒数

语法:

# 从左取
BLPOP key1 [key2 ] timeout
# 从右取
BRPOP key1 [key2 ] timeout

示例:

# 从msg列表头部获取,如果没有等待10秒
blpop msg 10
# 从msg列表尾部获取,如果没有等待10秒
brpop msg 10

提取并插入

从A列表尾部提起一个值,将提取的元素插入到B列表头部中并返回插入的值;如果A列表是空的会等待设定的秒数

语法:

BRPOPLPUSH listA listb timeout

示例:

127.0.0.1:6379> lpush lista 111
(integer) 1
127.0.0.1:6379> llen lista
(integer) 1
127.0.0.1:6379> llen listb
(integer) 0127.0.0.1:6379> brpoplpush lista listb 10
"111"
127.0.0.1:6379> llen lista
(integer) 0
127.0.0.1:6379> llen listb
(integer) 1
查看元素

通过索引查看列表中的元素,只获取查看,不会消费元素。语法:

LINDEX key index

示例

127.0.0.1:6379> lpush msg 111 222 333 444
(integer) 4
127.0.0.1:6379> lindex msg 2
"222"
127.0.0.1:6379> lindex msg 1
"333"
127.0.0.1:6379> lindex msg 0
"444"
移出元素

移除列表中指定元素的指定数量。语法:

LREM key count value

示例:

127.0.0.1:6379> lpush list1 11 22 33 22 44 22  55
(integer) 7
127.0.0.1:6379> lrange list1 0 -1
1) "55"
2) "22"
3) "44"
4) "22"
5) "33"
6) "22"
7) "11"
# 移出2个 22元素
127.0.0.1:6379> lrem list1 2 22
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "55"
2) "44"
3) "33"
4) "22"
5) "11"
截取列表

对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。语法:

LTRIM key start stop

示例:

127.0.0.1:6379> lpush list3 a b c d e f g h i j k
(integer) 11# 保留下标3-6之间的元素
127.0.0.1:6379> ltrim list3 3 6
OK
127.0.0.1:6379> lrange list3 0 -1
1) "h"
2) "g"
3) "f"
4) "e"

4.3.2 使用实例

(1)将列表视为队列(先进先出),如下:

# 下面实例中设定的key名为msg。
# 注意:当前库中不能存在key名为msg的string或hash类型的,不然添加信息会报错。
# key名为msg的可以不存在;如果存在则必须为list类型的,才能执行lpush命令# 向msg头部(左边)添加数据
127.0.0.1:6379> lpush msg hello
(integer) 1
127.0.0.1:6379> lpush msg world
(integer) 2# 从msg尾部(右边)提取数据
127.0.0.1:6379> rpop msg
"hello"
127.0.0.1:6379> rpop msg
"world"
127.0.0.1:6379> rpop msg
(nil)

(2)将列表视为堆栈(先入后出),如下:

# 向msg头部(左边)添加数据
127.0.0.1:6379> lpush msg 111
(integer) 1
127.0.0.1:6379> lpush msg 222
(integer) 2
127.0.0.1:6379> lpush msg 333
(integer) 3# 从msg头部(左边)提取数据
127.0.0.1:6379> lpop msg
"333"
127.0.0.1:6379> lpop msg
"222"
127.0.0.1:6379> lpop msg
"111"

rpop和lpop可以交替使用

4.4 Set

Redis 的 Set(集合)是 string(字符串)类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 的集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。因此,可以使用 Redis 的 Set(集合)高效地做如下事情:

  • 跟踪唯一项目(例如,跟踪访问给定博客文章的所有唯一IP地址)
  • 表示关系(例如,具有给定角色的所有用户的集合)
  • 执行常见的集合操作,如交集、并集和差集

注意:集合中最大的成员数为 2^32 - 1 (4294967295,每个集合可存储 40 多亿个成员)。大多数集合操作,包括添加、删除和检查项是否为集合成员,都是 O(1),这意味着他们的效率很高。但是,对于具有数十万或更多成员的大型集合,在运行 SMEMBERS 命令时应谨慎。此命令为 O(n),并在单个响应中返回整个集合。作为替代方案,考虑 SSCAN,它允许您迭代检索集合的所有成员。

4.4.1 Set命令

添加删除成员
# 向集合中添加成员
127.0.0.1:6379> sadd set:1 11 22 33
127.0.0.1:6379> sadd set:1 11 22 44 55
(integer) 2
# 重复的成员不会添加# 随机从集合中删除指定数量的成员,不写数量时,默认删一个
spop set:1 2# 根据元素内容,移出集合中一个或多个成员
srem set:1 33 44
获取集合成员
# 随机返回集合中的成员,不会移除;若不写数量时,默认返回一个
srandmember key 2# 集合中的成员数量
scard set:1# 查看集合中的所有成员
smembers set:1
集合交并差集
# 返回第一个集合与后续其他集合的差集
sdiff set:1 set:2 set:3
# 将后续集合中的差集,存储到第一个集合中
sdiffstore set:9 set:1 set:2 set:3# 返回所有集合的交集
sinter set:1 set:2 set:3
# 将后续集合中的交集,存储到第一个集合中
sinterstore set:8 set:1 set:2 set:3# 返回所有集合的并集,依然不会有重复数据
sunion set:1 set:2 set:3
# 将后续集合中的并集,存储到第一个集合中
sunionstore set:7 set:1 set:2 set:3
其他成员操作
# 判断元素是否是集合中的成员
sismember set:1 22
# 将某个元素成员从第一个集合移动到第二个集合中
smove set:1 set:4 11
迭代遍历
# 开启一个迭代器,遍历集合的所有成员
sscan set:1 0
# 开启一个迭代器,遍历集合中满足 *a* 规则的成员
sscan set:2 0 match *a*
# 开启一个迭代器,遍历集合中满足 *b* 规则的成员,并且要10个
sscan set:3 0 match *b* count 10

4.4.2 使用实例

(1)存储用户 123 和 456 的收藏图书ID集,如下:

127.0.0.1:6379> SADD user:123:favorites 347
(integer) 1
127.0.0.1:6379> SADD user:123:favorites 561
(integer) 1
127.0.0.1:6379> SADD user:123:favorites 742
(integer) 1
127.0.0.1:6379> SADD user:456:favorites 561
(integer) 1

(2)检查用户 123 是否喜欢图书 742 和 299,如下:

127.0.0.1:6379> SISMEMBER user:123:favorites 742
(integer) 1
127.0.0.1:6379> SISMEMBER user:123:favorites 299
(integer) 0

(3)用户 123 和 456 有共同喜欢的书吗?

127.0.0.1:6379> SINTER user:123:favorites user:456:favorites
1) "561"

(4)用户 123 收藏了多少本书?

127.0.0.1:6379> SCARD user:123:favorites
(integer) 3

4.5 zset

Redis 有序集合(Sorted Set)和集合(Set)一样,也是 string 类型元素的集合,并且集合元素不允许重复。

Redis 有序集合中每个元素都会关联一个 double 类型的分数(注意:分数允许重复),Redis 有序集合将按分数(score)进行排序。当多个元素具有相同的分数时,元素将按字典顺序排序。

可以使用zset实现排行榜功能。例如:您可以使用排序集轻松维护大型在线游戏中最高分的有序列表。

注意:有序集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。有序集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储 40 多亿个成员)。

在展示多个成员时,一定会根据分数排序展示,默认是从小到大。

4.5.1 zset命令

添加删除成员
# 向集合zset:1中添加两个成员:分数10的成员user1、分数20的成员user2
zadd zset:1 10 user1 20 user2# 删除集合中指定的一个或多个成员
zrem zset:1 user1 user2
顺序获取成员
# 分数由小到大排序情况下,根据给定排名区间,返回集合中的成员
zrange zset:1 0 3	# 返回排名0-3之间的
zrange zset:1 0 -1	# 返回所有成员
zrange zset:1 0 -1 withscores # 返回所有成员,并显示分数# 分数由大到小排序情况下
zrevrange zset:1 0 -1 withscores
获取成员信息
# 分数从小到大排序下,返回集合中指定成员的排名
zrank zset:1 user2# 分数从大到小排序下,返回集合中指定成员的排名
zrevrank zset:1 user2# 获取zset:1集合中的成员个数
zcard zset:1# 返回成员的分数值
zscore zset:1 user1
修改成员分数
# 给zset:1集合中的成员user2,添加50分
zincrby zset:1 50 user2
基于分数的命令
# 获取zset:1集合中,成员分数满足0-100的个数
zcount zset:1 0 100# 从小到大顺序下,通过分数区间,展示成员名称。可选的同时展示分数,可选的同时进行分页
zrangebyscore zset:1 10 50 withscores limit 1 2# 从大到小顺序下,通过分数区间,展示成员名称。可选的同时展示分数,可选的同时进行分页
zrevrangebyscore zset:1 20 100 withscores limit 0 1# 移除有序集合中给定的分数区间的所有成员
zremrangebyscore zset:key 10 100# 移除根据分数从小到大排名情况下,排名0-2的成员。排名第一的索引是0
zremrangebyrank zset:1 0 2
基于成员名的命令
# 获取zset:1集合中,按照成员名称字典排序情况下,满足user1-user3的成员个数
# [ 是语法结构,需要带上; 或者是写全了[user1]
zlexcount zset:1 [user1 [user3
zlexcount zset:1 [usa] [usz] # 不完全匹配user1这种样式也可以# 通过字典区间返回有序集合的成员名称,可以进行分页展示,第一页的前两条
zrangebylex zset:1 [a [y limit 1 2# 移除有序集合中给定的字典区间的所有成员
zremrangebylex zset:1 [c [d
交并集处理
# 将后面两个集合的交集,储存到前面的第一个集合中
# 中间的2表示,后面要计算2个集合。要计算集合集合,这里就写几
zinterstore zset:9 2 zset:1 zset:2# 并集的
zunionstore zset:8 2 zset:1 zset:2
迭代遍历

迭代有序集合中的元素(包括元素成员和元素分值),语法:

ZSCAN key cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> zadd zset:key 100 google 200 baidu 400 bing 300 yahoo
(integer) 4
127.0.0.1:6379> zscan zset:key 0 match *g
1) "0"
2) 1) "bing"2) "400"
127.0.0.1:6379> zscan zset:key 0 match *g*
1) "0"
2) 1) "google"2) "100"3) "bing"4) "400"

4.5.2 使用实例

(1)随着玩家分数的变化,更新实时排行榜。例如:

127.0.0.1:6379> zadd leaderboard:455 100 user:1
(integer) 1
127.0.0.1:6379> ZADD leaderboard:455 75 user:2
(integer) 1
127.0.0.1:6379> ZADD leaderboard:455 101 user:3
(integer) 1
127.0.0.1:6379> ZADD leaderboard:455 15 user:4
(integer) 1
127.0.0.1:6379> ZADD leaderboard:455 275 user:2
(integer) 0

注意:在最后的 ZADD 调用中,user:2 的分数被更新了。

(2)获得前3名球员的得分,如下:

127.0.0.1:6379> ZREVRANGE leaderboard:455 0 2 WITHSCORES
1) "user:2"
2) "275"
3) "user:3"
4) "101"
5) "user:1"
6) "100"

(3)用户2 的级别是多少?

127.0.0.1:6379> ZREVRANK leaderboard:455 user:2
(integer) 0

ZREVRANK 命令用来返回存储在 key 的排序集中成员的排名,分数从高到低排序。排名(或索引)从 0 开始,这意味着得分最高的成员的排名为 0。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/5611.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏设备升级怎么选?RTX4070独显,ToDesk云电脑更具性价比

过新年、添喜气!正逢节期来临不知道各位是否都跟小编一样在考虑购置生活中的各样所需呐? 25年可谓是3A游戏大作之年,例如《GTA6》《文明7》《死亡搁浅2》《刺客信条:影》下半年落地的《塞尔达传说:新篇章》《生化危机9…

网络安全解决方案分享:推荐十款网络准入控制系统,保护企业网络安全

随着企业信息化进程的不断推进,企业网络安全面临的威胁愈加复杂。网络准入控制(NAC, Network Access Control)系统作为保障企业网络安全的核心技术,无论是防止外部攻击、阻止内部滥用,还是确保设备符合合规要求&#x…

WebSocket实现私聊私信功能

目录 后端pom.xmlConfig配置类Controller类DTO 前端安装相关依赖websocketService.js接口javascripthtmlCSS 效果展示简单测试连接: 报错解决方法1、vue3 使用SockJS报错 ReferenceError: global is not defined 后面将继续完善,待更新... 后端 pom.xml…

【PHP】部署和发布PHP网站到IIS服务器

欢迎来到《小5讲堂》 这是《PHP》系列文章,每篇文章将以博主理解的角度展开讲解。 温馨提示:博主能力有限,理解水平有限,若有不对之处望指正! 目录 前言安装PHP 稳定版本线程安全版解压使用 PHP配置 配置文件扩展文件…

电梯系统的UML文档07

从这个类中得到的类图,构划出了软件的大部分设计。 系统结构视图提供软件和整个系统结构最复杂的也是最优雅的描述。和通常的软件系统相比,在分布式嵌入系统中了解系统组件如何协同工作是非常重要的。毕竟,每个类图仅仅是一个系统的静态设计…

低代码系统-产品架构案例介绍、明道云(七)

今天分析另外一个零代码、低代码产品-明道云,跟所有低代码产品的架构图一样,高、大、炫、美。 依然是从下至上,从左到右的顺序。 开发层 搭建中心 表单、流程、报表、用户中心,还是这些内容,自定义打印很多平台都有&am…

Linux编译安装Netgen/NGSolve

本文记录Linux下编译安装Netgen/NGSolve的流程。 零、环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1oneAPI2024.2.1 一、安装依赖 1.1 VS Code 下载并安装VS Code,然后安装以下插件, Task Explorer Output Colorizer …

RabbitMQ的消息可靠性保证

文章目录 1.环境搭建1.common-rabbitmq-starter 配置防止消费者抢消息(基础配置)2.common-rabbitmq-starter-demo下创建一个生产者一个消费者 2.生产者可靠性1.开启消息超时重试机制2.生产者开启ConfirmCallback消息确认机制1.application.yml2.TestConf…

transformers使用过程问题

transfomers新旧版本冲突,和accelerate、datasets、evaluate这些库直接也经常会发生冲突 我使用了下面的版本,暂时没有冲突,如果有冲突再更新 transformers4.41.2 datasets2.20.0 accelerate0.31.0 evaluate0.4.2pip install transformers安…

Text2SQL 智能报表方案介绍

0 背景 Text2SQL智能报表方案旨在通过自然语言处理(NLP)技术,使用户能够以自然语言的形式提出问题,并自动生成相应的SQL查询,从而获取所需的数据报表,用户可根据得到结果展示分析从而为结论提供支撑&#…

Idea调试的时候字符串路径乱码 poi解析时表单中文名字正确,但是找不到

目录 原因 解决措施 POI表单中文名字正确但是找不到 原因 1.编码格式冲突 2.文件编码多次转换&#xff0c;已经凌乱 解决措施 1.找到工程目录下的文件夹【.idea】 2.进入【encodings.xml】文件 3.将【encodings.xml】中&#xff0c;除了<file url"PROJECT"&g…

LAYA3.0 组件装饰器说明

原文 在LayaAirIDE中&#xff0c;如果想在IDE内展示组件脚本的属性&#xff0c;需要通过装饰器的规则来实现。下面分别介绍四种装饰器。 文章目录 一、regClass()二、property()2.1 组件属性的常规使用2.2 属性访问器的装饰器使用2.3 是否序列化保存2.4 组件属性是否在IDE中显…

精选100+套HTML可视化大屏模板源码素材

大屏数据可视化以大屏为主要展示载体的数据可视化设计。 “大面积、炫酷动效、丰富色彩”&#xff0c;大屏易在观感上给人留下震撼印象&#xff0c;便于营造某些独特氛围、打造仪式感。 原本看不见的数据可视化后&#xff0c;便能调动人的情绪、引发人的共鸣。 使用方法&…

Unity中实现伤害跳字效果(简单好抄)

第一步骤安装并导入Dotween插件&#xff08;也可以不用导入之后直接下载我的安装包&#xff09; 官网DOTween - 下载 第二步&#xff1a; 制作跳字预制体 建议把最佳适应打开&#xff0c;这样就不怕数字太大显示不全了。 第三步&#xff1a;创建一个空对象并编写脚本JumpNumbe…

Java复习第四天

一、代码题 1.相同的树 (1)题目 给你两棵二叉树的根节点p和q&#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1: 输入:p[1,2,3]&#xff0c;q[1,2,3] 输出:true示例 2: 输…

【2024年华为OD机试】(C/D卷,200分)- 5G网络建设 (JavaScriptJava PythonC/C++)

一、问题描述 题目描述 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N。接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通。不同基站之间假设光纤的成本各不相同&#xff0c;且有些节点之间已经存在光纤相连。 …

Kubernetes 集群中安装和配置 Kubernetes Dashboard

前言 上篇成功部署Kubernetes集群后&#xff0c;为了方便管理和监控集群资源&#xff0c;安装Kubernetes Dashboard显得尤为重要。Kubernetes Dashboard 是一个通用的、基于 Web 的 UI&#xff0c;旨在让用户轻松地部署容器化应用到 Kubernetes 集群&#xff0c;并对这些应用进…

前端【7】javascript-dom操作

目录 DOM 加载与脚本执行的时序问题 1. 将 <script> 标签放到 HTML 末尾 2.使用 defer 属性 3. 使用 window.onload 一、获取元素 1、getElementById 2、getElementsByClassName 3、getElementsByTagName 4、querySelector和querySelectorALL 5、对象的属性关…

python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖

【1】引言 前序学习了使用numpy创建单通道的灰色图像&#xff0c;并对灰色图像的局部进行了颜色更改&#xff0c;相关链接为&#xff1a; python学opencv|读取图像&#xff08;九&#xff09;用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 之后又学习了使用numpy创…

【2024年终总结】我与CSDN的一年

&#x1f449;作者主页&#xff1a;心疼你的一切 &#x1f449;作者简介&#xff1a;大家好,我是心疼你的一切。Unity3D领域新星创作者&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6; &#x1f449;记得点赞 &#x1f44d; 收藏 ⭐爱你们&#xff0c;么么哒 文章目录 …