redis简介
| 基础数据类型 | 高级数据类型 |
|---|---|
| 字符串 String | 消息队列 Stream |
| 列表 List | 地理空间 Geospatial |
| 集合 Set | HyperLogLog |
| 有序集合 SortedSet | 位图 Bitmap |
| 哈希 Hash | 位域 Bitfield |
Redis优势
性能极高 基于内存
数据类型丰富,单键值对最大支持512M大小的数据
简单易用,支持所有主流编程语言
支持数据持久话、主从复制、烧饼模式等高级可用特性
配置好环境变量
打开cmd 启动服务
cmd
# 启动redis服务
redis-server.exe
# 另一个端口 连接
redis-cli 127.0.0.1 -p 6379
# 或
redis-cli
# 或
redis-cli -raw
一 基础命令
1 ping 心跳命令
输入ping 命令,响应pong,则客户端与Redis正常连接
cmd
redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
2 get / set 读写命令
set key value 会将指定 key-value 写入到DB。get key 则会读取到指定key的value值
cmd
127.0.0.1:6379> set name libai
OK
127.0.0.1:6379> get name
"libai"
127.0.0.1:6379>
3 select 切换数据库
默认数据库为 0 ,redis默认有16个数据库。这个在Redis Desktop Manager(RDM)图形客户端中可以直观地看到。默认使用地是0号DB,可以通过select db 索引来切换 DB。如图,切换到1号DB:
cmd
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379>
4、dbsize查看key数量
dbsize 命令可以查看当前数据库中的key数量
keys * 查看当前数据库中存在的键
cmd
127.0.0.1:6379> dbsize
(integer) 3
127.0.0.1:6379> keys *
1) "h1"
2) "age"
3) "name"
5 flushdb 删除所有数据
flushdb 命令,删除当前数据库所有数据,不影响其他数据库
cmd
127.0.0.1:6379[1]> dbsize
(integer) 1
127.0.0.1:6379[1]> flushdb
OK
127.0.0.1:6379[1]> dbsize
(integer) 0
127.0.0.1:6379[1]>
6 flushall 删除全部db数据
cmd
127.0.0.1:6379[1]> flushall
OK
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379>
二 Key 相关操作命令
1 keys 数量
- 格式:KEYS pattern
- 功能:查找所有符合给定模式pattern 的 key,pattern 为正则表达式
- 说明:KEYS 的速度非常快,但在一个大的数据库中使用它可能会阻塞当前服务器的服务。所有生产环境中一般不适用该命令,而使用scan命令代替
cmd
#查找 key 名包含 am 的key
127.0.0.1:6379> keys *
1) "name"
2) "nan"
3) "he"
4) "age"
5) "h1"
127.0.0.1:6379> keys *am*
1) "name"
127.0.0.1:6379>
2 exists 是否存在
- 格式:exists key
- 功能:检查给定 key 是否存在
- 说明:若key 存在 返回 1, 否则 返回0
cmd
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists name1
(integer) 0
127.0.0.1:6379>
3 del 删除
- 格式:del key【key ...】
- 功能:删除给定的一个或多个key。不存在会忽略
- 说明:返回被删除key的数量
cmd
127.0.0.1:6379> set a1 1
OK
127.0.0.1:6379> set a2 1
OK
127.0.0.1:6379> set a3 1
OK
127.0.0.1:6379> del a1 a3 a3
(integer) 2
127.0.0.1:6379> del a1 a3 a2
(integer) 1
127.0.0.1:6379>
4 rename 改名
- 格式:rename key newkey
- 功能:将 key 改名 为 newkey
- 说明:当 key 和 newkey 相同,或者 key 不存在时,返回一个错误。当 newkey 已经存在时,rename 命令将覆盖旧值。改名成功时提示 OK,失败时候返回错误
cmd
127.0.0.1:6379> rename nan newyear
OK
127.0.0.1:6379> rename nan newyear
(error) ERR no such key
127.0.0.1:6379> get newyear
"10"
5 move 移动
- 格式:move key db
- 功能:将当前数据库的key移动到给定的数据库 db 中
- 说明:如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定key,或者key不存在于当前的数据库,那么move没有任何效果。移动成功返回1,失败返回0
cmd
127.0.0.1:6379> keys *
1) "name"
2) "newyear"
3) "h1"
4) "he"
5) "age"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> set h1 0
OK
127.0.0.1:6379[1]> move h1 0
(integer) 0
127.0.0.1:6379[1]> move h1 2
(integer) 1
127.0.0.1:6379[1]>
6 type 判断类型
- 格式:type key
- 功能:返回 key 所存储的值的类型
- 说明:返回值有以下六种
- none key 不存在
- string 字符串
- list 列表
- set 集合
- zset 有序集合
- hash 哈希表
cmd
127.0.0.1:6379> type name
string
127.0.0.1:6379>
7 expire/pexpire 过期时间
- 格式:expire key seconds
- 功能:为给定 key 设置生存时间。当key过期时(生存时间为0),他会自动删除。expire的时间单位为秒,pexpire的时间单位为毫秒。在Redis中,带有生存时间的key被称为"易失"(volatile)
- 说明:生存时间设置成功返回1。若key不存在时返回0。rename操作不会改变key的生存时间
cmd
127.0.0.1:6379> expire kk 100
(integer) 1
127.0.0.1:6379> ttl kk
(integer) 97
127.0.0.1:6379>
8、ttl/pttl 查看时间
- 格式:ttl key
- 功能:ttl,time to love,返回给定key的剩余生存时间。
- 说明:其返回值存在三种可能:
- 1 当key不存在 返回 -2
- 2 当key存在 但没有设置生存时间,返回 -1
- 3 否则,返回 key 的剩余生存时间,ttl 命令 返回的时间单位为秒,而pttl 命令返回毫秒
cmd
127.0.0.1:6379> keys *
1) "name"
2) "newyear"
3) "h1"
4) "he"
5) "age"
127.0.0.1:6379> ttl no
(integer) -2
127.0.0.1:6379> ttl name
(integer) -1
127.0.0.1:6379> set nn 1
OK
127.0.0.1:6379> expire nn 100
(integer) 1
127.0.0.1:6379> ttl nn
(integer) 93
127.0.0.1:6379> pttl nn
(integer) 84532
127.0.0.1:6379>
9 persist 去除时间
- 格式:persist key
- 功能:去除给定key 的生存时间,将这个key 从"易失的"转换成"持久的"。
- 说明:当生存时间移除成功是,返回1;若key不存在或key 没有设置生存时间,则返回0
cmd
127.0.0.1:6379> keys *
1) "name"
2) "h2"
3) "newyear"
4) "h1"
5) "he"
6) "age"
127.0.0.1:6379> expire h1 100
(integer) 1
127.0.0.1:6379> ttl h1
(integer) 97
127.0.0.1:6379> persist h1
(integer) 1
127.0.0.1:6379> ttl h1
(integer) -1
127.0.0.1:6379> persist h1
(integer) 0
127.0.0.1:6379> persist h11
(integer) 0
127.0.0.1:6379>
10 radomkey 随机key
- 格式:randomkey
- 功能:从当前数据库中随机返回(不删除)一个key
- 说明:当数据库不为空,返回一个key,为空返回null
cmd
127.0.0.1:6379> dbsize
(integer) 6
127.0.0.1:6379> randomkey
"name"
127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> randomkey
(nil)
11 scan 没理解
- 格式:SCAN cursor 【MATCH pattern】【COUNT count]】【TYPE type】
- 功能:用于迭代数据中数据的数据库键,其各个选项的意义为:
- cursor:本次迭代开始的游标。
- pattern :本次迭代要匹配的 key 的模式。
- count :本次迭代要从数据集里返回多少元素,默认值为 10 。
- type:本次迭代要返回的value 的类型,默认为所有类型。
SCAN 命令是一个基于游标 cursor 的迭代器:SCAN 命令每次被调用之后,都会向用户返回返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标,而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数,以此来延续之前的迭代过程。当 SCAN 命令的游标参数被设置为 0 时,服务器将开始一次新的迭代。如果新游标返回 0表示迭代已结束。
- 说明:使用间断的、负数、超出范围或者其他非正常的游标来执行增量式迭代不会造成服务器崩溃。
当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。由于 scan 命令每次执行都只会返回少量元素,所以该命令可以用于生产环境,而不会出现像 KEYS 命令带来的服务器阻塞问题。
增量式迭代命令所使用的算法只保证在数据集的大小有界的情况下迭代才会停止,换句话说,如果被迭代数据集的大小不断地增长的话,增量式迭代命令可能永远也无法完成一次完整迭代。即当一个数据集不断地变大时,想要访问这个数据集中的所有元素就需要做越来越多的工作, 能否结束一个迭代取决于用户执行迭代的速度是否比数据集增长的速度更快。
- 相关命令:另外还有 3 个 scan 命令用于对三种类型的 value 进行遍历。
- hscan:属于 Hash 型 Value 操作命令集合,用于遍历当前 db 中指定 Hash 表的所有 field-value 对。
- sscan:属于 Set 型Value 操作命令集合,用于遍历当前 db 中指定 set 集合的所有元素
- zscan:属于 ZSet 型 Value 操作命令集合,用于遍历当前 db 中指定有序集合的所有元素(数值与元素值)
三 String型Value操作命令
Redis存储数据的Value可以是一个String类型数据。String类型的Value是Redis中最基本,最常见的类型。String类型的Value中可以存放任意数据,包括数值型,甚至是二进制的图片、音频、视频、序列号对象等。一个String类型的Value最大是512大小。
1 set *
- 格式:SET key value 【EX seconds | PX milliseconds】【NX|XX】
- 功能:SET 除了可以直接将 key 的值设为 value 外,还可以指定一些参数。
- EX seconds:为当前 key 设置过期时间 ,单位秒。等价于 SETEX 命令。
- PX milliseconds:为当前 key 设置过期时间 ,单位毫秒。等价于 PSETEX 命令。
- NX:指定的 key 不存在才会设置成功,用于添加指定的 key。等价于 SETNX 命令。
- XX:指定的 key 必须存在才会设置成功,用于更新指定key 的value。
- 说明:如果value 字符串中带有空格,则该字符串需要使用双引号或单引号引起来,否则会认为 set 命令的参数数量不正确,报错。
- 注意: 设置value 中包含字符串时 要用 "" 【引号包含起来】 如:set key "hello word"
cmd
127.0.0.1:6379> set nkey libai EX 1000 NX # EX 1000秒后过期 、NX nkey不存在才能设置成功
OK
127.0.0.1:6379> ttl nkey
(integer) 981
127.0.0.1:6379> set hello libai XX # XX当已存在 hello 才能设置成功
(nil)
127.0.0.1:6379> get nkey
"libai"
127.0.0.1:6379> set nkey hhh XX # XX nkey 存在 设置成功 、注意这里的过期时间会变更为未设置
OK
127.0.0.1:6379> get nkey
"hhh"
127.0.0.1:6379> ttl nkey
(integer) -1
127.0.0.1:6379>
2 setex/psetex 过期时间
- 格式:SETEX/PSETEX key seconds value
- 功能:set expire,其不仅为 key 指定了value,还为其设置了生存时间。setex 的单位为秒,psetex 的单位为毫秒。
- 说明:如果 key 已经存在, 则覆写旧值。该命令类似于以下两个命令,不同之处是, SETEX 是一个原子性操作,关联值和设置生存时间两个动作会在同一时间内完成,该命令在 Redis 用作缓存时,非常实用。
- SET key value
- EXPIRE key seconds # 设置生存时间
cmd
127.0.0.1:6379> set a1 12 ex 100 #同下 【功能效果相同】
OK
127.0.0.1:6379> setex a2 12 100 #同上
OK
127.0.0.1:6379> ttl a1
(integer) 79
127.0.0.1:6379> ttl a2
(integer) 1
127.0.0.1:6379> EXPIRE a2 1000 # 设置过期时间
(integer) 1
127.0.0.1:6379> ttl a2
(integer) 962
3 setnx 不存在1
- 格式:SETNX key value
- 功能:set if Not eXists,将 key 的值设为 value,当且仅当 key 不存在。若给定 key 已经存在,则 SETNX 不做任何动作。成功=》返回 1,否则=》返回 0
- 说明:该命令等价 set key value nx
cmd
127.0.0.1:6379> keys *
1) "name"
2) "a2"
127.0.0.1:6379> setnx a1 1
(integer) 1
127.0.0.1:6379> setnx a2 2
(integer) 0
127.0.0.1:6379>
4 getset 反旧 更新
- 格式:getset key value
- 功能:将给定key的值设为value,并返回key的旧值
- 说明:当key存在但不是字符串类型时,返回一个错误;当key不存在时,返回 nil
cmd
127.0.0.1:6379> get a1
"1"
127.0.0.1:6379> GETSET a1 111
"1"
127.0.0.1:6379> get a1
"111"
127.0.0.1:6379> GETSET a2 222
(nil)
127.0.0.1:6379>
5 mset/msetnx 写多值/nx
- 格式:mset/msetnx key value [key value ...]
- 功能:同时设置一个或多个key-value 对
- 说明:如果某个给定 key 已经存在,那么 mset 会用新值覆盖旧值,如果这不是你想要的效果,请考虑使用msetnx命令:它只会在所给定key都不存在的情况下进行设置操作。mset/msetnx是一个原子性(atomic)操作,所有给定key都会在同一时间内被设置,某些给定key被更新而另一些给定key没有改变的情况不可能发生。该命令永不失败。
- mset:只要命令格式正确,总会成功执行,返回
OK - msetnx:所有键都不存在,设置成功,返回
1,任何一个键已存在,设置失败,返回0
- mset:只要命令格式正确,总会成功执行,返回
cmd
127.0.0.1:6379> mset t1 1 t2 2 t3 3
OK
127.0.0.1:6379> keys *
1) "t1"
2) "t2"
3) "t3"
127.0.0.1:6379> msetnx z1 1 z2 2 z3 3 t1 1
(integer) 0
127.0.0.1:6379>
6 mget 多返回值
- 格式:mget key [key ...]
- 功能:返回所有(一个或多个)给定 key 的值
- 说明:如果给定的 key 里面,有某个 key 不存在,那么这个key 返回特殊 nil。因此,该命令永不失败。
cmd
127.0.0.1:6379> mget a1 a2 a3
1) "111"
2) "222"
3) (nil) #不存在
127.0.0.1:6379> mget t1 t2 t3
1) "1"
2) "2"
3) "3"
127.0.0.1:6379>
7 append 追加
- 格式:append key value
- 功能:如果key已经存在并是一个字符串,append命令将value追加到key原来的值的末尾。如果key不存在,append就简单地将给定 key 设为 value ,就像执行set key value 一样。
- 说明:追加 value 之后,key 中字符串的长度。
cmd
127.0.0.1:6379> set s abc
OK
127.0.0.1:6379> get s
"abc"
127.0.0.1:6379> append s de
(integer) 5
127.0.0.1:6379> get s
"abcde"
127.0.0.1:6379> append s1 12345
(integer) 5
127.0.0.1:6379> get s1
"12345"
8 incr/decr 增/减 1
- 格式:incr key 或 decr key
- 功能:increment ,自动递增。将 key 中存储的数字 +1 ,decrement ,自动递减。将 key中存储的数字值 -1
- 说明:如果 key 不存在,那么key 的值会被初始化为0,然后在执行 增1 / 减 1 操作。如不哦值不能表示数字,那么返回要给错误提示。如果执行不正确,则返回 增1 / 减1 后的值。
cmd
127.0.0.1:6379> set i 2
OK
127.0.0.1:6379> incr i # +1
(integer) 3
127.0.0.1:6379> get i
"3"
127.0.0.1:6379> incr ii # 不存在ii 则初始化0 +1
(integer) 1
127.0.0.1:6379> get ii
"1"
127.0.0.1:6379> decr ii # -1
(integer) 0
127.0.0.1:6379> get ii
"0"
127.0.0.1:6379> decr ii
(integer) -1
127.0.0.1:6379> get ii
"-1"
127.0.0.1:6379>
9 incrby/decrby 增/减指定值
- 格式:incrby key increment 或 decrby key decrement
- 功能:将 key 中存储的数字值增加/减少指定的数值,这个数值只能是整数,可以是负数,但不能是小数
- 说明:如果 key 不存在,那么key 的值会被初始化为0,然后在执行增加/减少操作。如果值不能表示为数字,那么返回一个错误提示
cmd
127.0.0.1:6379> get i
"3"
127.0.0.1:6379> incrby i 10
(integer) 13
127.0.0.1:6379> get i
"13"
127.0.0.1:6379> incrby name 10
(error) ERR value is not an integer or out of range
127.0.0.1:6379> incrby i11 10
(integer) 10
127.0.0.1:6379>
10 incrbyfloat 增浮点
- 格式:incrbyfloat key increment
- 功能:为 key 中所存储的值加上浮点数增量 increment
- 说明:与之前的说明相同。没有 decrbyfloat 命令,但 increment 为负数可以实现减操作效果。
cmd
127.0.0.1:6379> get i
"13"
127.0.0.1:6379> incrbyfloat i 2.56
"15.56"
127.0.0.1:6379> incrbyfloat i -10
"5.56"
127.0.0.1:6379> get i
"5.56"
127.0.0.1:6379>
11 strlen 长度
- 格式:strlen key
- 功能:返回 key 所存储的字符串值的长度
- 说明:当 key 存储的不是字符串值时,返回一个错误; 当 key 不存在时,返回 0
cmd
127.0.0.1:6379> get i
"5.56"
127.0.0.1:6379> strlen i
(integer) 4
127.0.0.1:6379> get name
"libai"
127.0.0.1:6379> strlen name
(integer) 5
127.0.0.1:6379>
12 grange 截取
- 格式:getrange key start end
- 功能:返回 key 中字符串值的字符串,字符串的截取范围由 start 和 end 两个偏移量决定,包括 start 和 end 在内
- 说明:end 必须要比 start 大。支持负数偏移量,表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以为类推
cmd
127.0.0.1:6379> set i 123456
OK
127.0.0.1:6379> getrange i 0 4 # 第一 到 第五个
"12345"
127.0.0.1:6379> getrange i 0 -2 # 第一 到 倒数第二个
"12345"
127.0.0.1:6379>
13 setrange 替换
- 格式:setrange key offset value
- 功能:用 value 参数替换给定 key 所存储的字符串值 str, 从偏移量 offset 开始
- 说明:当 offset 值大于 str长度时,中间使用 零字节\x00 填充,即 0000 0000 字节填充;对于不存在的key 当作空串处理。
cmd
127.0.0.1:6379> get i
"123456"
127.0.0.1:6379> setrange i 1 100 #从第二个 开始 替换成100
(integer) 6
127.0.0.1:6379> get i
"110056"
127.0.0.1:6379> setrange i 10 123
(integer) 13
127.0.0.1:6379> get i
"110056\x00\x00\x00\x00123" #110056 0 0 0 0123
127.0.0.1:6379>
14 位操作命令
名称中包含 BIT 的命令,都是对二进制位的操作命令,例如,setbit、getbit、bitcount、bittop、bitfield,这些命令不常用。
15 典型应用场景
Value 为 String 类型的应用场景很多,这里仅举这种典型应用场景的例子:
- 数据缓存:Redis 作为数据缓存层,MySQL 作为数据存储层。应用服务器首先从 Redis 中获取数据,如果缓存层中没有,则从MySQL 中获取后先存入缓存层再返回给应用服务器。
- 计数器:在 Redis 中写入一个 value 为数值型的 key 作为平台计数器、视频播放计数器等。每个有效客户端访问一次,或视频每播放一次,都是直接修改 Redis 中的计数器,然后再以异步方式持久化到其它数据源中,例如持久化到 MySQL。
- 共享Session:对于一个分布式应用系统,如果将类似用户登录信息这样的 Session 数据保存在提供登录服务的服务器中,那么如果用户再次提交像收藏、支付等请求时可能会出现问题:在提供收藏、支付等服务的服务器中并没有该用户的 Session 数据,从而导致该用户需要重新登录。对于用户来说,这是不能接受的。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。这样就不会引发"重新登录"问题。

- 限速器:现在很多平台为了防止 DoS(Denial of Service,拒绝服务)攻击,一般都会限制一个 IP不能在一秒内访问超过 n 次。而 Redis 可以可以结合 key 的过期时间与 incr 命令来完成限速功能,充当限速器。注意,其无法防止 DDoS(Distributed Denial of Service,分布式拒绝服务)攻击。
四 Hash型value操作命令
无限字符 ----Hashing----> 有限数字
Redis 存储数据的value可以是一个hash类型。hash类型也称为hash表、字典等。
- hash表就是一个映射 Map ,也就是由键-值对构成,为了与整体的 key 进行区分,这里的键称为 field,值称为 value。注意,Redis 的Hash 表中的 field-value 对 均为 String 类型
1 hset 存key值
- 格式:HSET key field value
- 功能:将哈希表 key 中的域 field 的值设为 value【不能更新已存在】
- 说明:如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。如果域 field 已经存在哈希表中,旧值将被覆盖。如果 field 时哈希表中的一个新建域,并且设置成功,返回1.如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回0.
cmd
127.0.0.1:6379> hset employee name libai age 1000 gender man #存储值
(integer) 3
127.0.0.1:6379> hgetall employee # 获取所有哈希值
1) "name"
2) "libai"
3) "age"
4) "1000"
5) "gender"
6) "man"
127.0.0.1:6379> hget employee name #取出name 键对应的 值 libai
"libai"
127.0.0.1:6379>
2 hget 获取key值
- 格式:GET key field
- 功能:返回哈希表 key 中给定域 field 的值
- 说明:当给定域不存在或是给定 key 不存在 ,返回 nil
cmd
127.0.0.1:6379> hget employee name
"libai"
127.0.0.1:6379> hget employee libai
(nil)
127.0.0.1:6379>
3 hmset 存在覆盖
- 格式:HMSET key field value 【fuekd value ...】
- 功能:同时将多个 field-value (域-值)对设置到哈希表 key 中
- 说明:此命令会覆盖哈希表中已存在的域。如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。如果命令执行成功,返回OK。当 key 不是哈希表(hash)类型时,返回一个错误。
cmd
127.0.0.1:6379> hmset employee age 18 grade first hobby eat #已存在会覆盖 age 1000变18
(integer) 3
127.0.0.1:6379> hgetall employee
1) "name"
2) "libai"
3) "age"
4) "18"
5) "gender"
6) "man"
7) "grade" # 以下是新追加的
8) "first"
9) "hobby"
10) "eat"
127.0.0.1:6379>
4 hmget 返回多值
- 格式:HMGET key field 【field ...】
- 功能:按照给出顺序返回哈希表 key 中一个或多个域的值
- 说明:如果给定的域不存在于哈希表中,那么返回一个 nil 值。因为不存在的 key 被当作一个空哈希来处理,所有对一个不存在的key进行 HMGET 操作将返回一个知带有nil值的表
cmd
127.0.0.1:6379> hgetall employee
1) "name"
2) "libai"
3) "age"
4) "1000"
5) "gender"
6) "man"
7) "grade"
8) "first"
9) "hobby"
10) "eat"
127.0.0.1:6379> hmget employee name age gender grade # 按顺序返回特定值
1) "libai"
2) "1000"
3) "man"
4) "first"
127.0.0.1:6379>
5 hgetall 返回所有值
- 格式:HGETALL key
- 功能:返回哈希表 key 中 所有域和值
- 说明:在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。若 key 不存在,返回空列表。若 key 中包含大量元素,则该命令可能回阻塞 Redis 服务。所以生产环境一般不使用 该命令,而使用 hscan命令代替
cmd
127.0.0.1:6379> hgetall employee
1) "name"
2) "libai"
3) "age"
4) "1000"
5) "gender"
6) "man"
7) "grade"
8) "first"
9) "hobby"
10) "eat"
127.0.0.1:6379> hgetall student
(empty array)
127.0.0.1:6379>
6 hsetnx 新建域值,存在不变
- 格式:HSETNX key field value
- 功能:将哈希表 key 中的域,field 的值设置为 value,当且仅当域 field 不存在
- 说明:若域 field 已经存在,该操作无效。如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令
cmd
127.0.0.1:6379> hsetnx employee name qin # 已存在不变
(integer) 0
127.0.0.1:6379> hsetnx employee id 20250505 # 原来无 新建id
(integer) 1
127.0.0.1:6379> hmget employee name id # 返回键对应值
1) "libai"
2) "20250505"
127.0.0.1:6379>
7 hdel 删除指定域
- 格式:HDEL key field 【field ...】
- 功能:删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略
- 说明:返回被成功移除的域数量,不包括被忽略的域
cmd
127.0.0.1:6379> hgetall employee
1) "name"
2) "libai"
3) "age"
4) "1000"
5) "gender"
6) "man"
7) "grade"
8) "first"
9) "hobby"
10) "eat"
11) "id"
12) "20250505"
127.0.0.1:6379> hdel employee grade hobby #删除存在
(integer) 2
127.0.0.1:6379> hdel employee hobby #删除不存在
(integer) 0
127.0.0.1:6379>
8 hexists 是否存在
- 格式:HEXISTS key field
- 功能:查看哈希表 key 中给定域 field 是否存在
- 说明:如果哈希表含有给定域,返回1.如果不含有给定域,或 key 不存在,返回0
cmd
127.0.0.1:6379> hgetall employee
1) "name"
2) "libai"
3) "age"
4) "22"
5) "gender"
6) "man"
7) "id"
8) "123"
9) "id1"
10) "23"
127.0.0.1:6379> hexists employee name
(integer) 1
127.0.0.1:6379> hexists employee name1
(integer) 0
127.0.0.1:6379>
9 hincrby/hincrbyfloat 运算
- 格式:HINCRBY key field increment
- 功能:为哈希表 key 中的域 field 的值加上增量 increment。hincrby 命令只能增加整数值,而 hincrbyfloat 可以增加小数值
- 说明:增量也可以为负数,相当于对给定域进行减法操作。如果key不存在,一个新的哈希表被创建并执行 HINCRBY 命令。如果域 field 不存在,那么执行命令之前,域的值被初始化为0。对一个存储字符串值的域 field 执行HINCRBY 命令将造成要给错误。
cmd
127.0.0.1:6379> hgetall employee
1) "name"
2) "libai"
3) "age"
4) "22"
5) "id1"
6) "23"
127.0.0.1:6379> hexists employee name
(integer) 1
127.0.0.1:6379> hexists employee name1
(integer) 0
127.0.0.1:6379> HINCRBY employee id1 2 #增加2
(integer) 25
127.0.0.1:6379> hget employee id1
"25"
127.0.0.1:6379> HINCRBYFLOAT employee id1 -10.2 #减少10.2 返回浮点数
"14.8"
127.0.0.1:6379> hget employee id1
"14.8"
127.0.0.1:6379>
10 hkeys/hvals 所有键/值
- 格式:hkeys key 或 hvals key
- 功能:返回哈希表 key 中的所有域/值
- 说明:当 key 不存在时,返回一个表。
cmd
127.0.0.1:6379> hkeys employee #所有域【键】
1) "name"
2) "age"
3) "gender"
4) "id"
5) "id1"
127.0.0.1:6379> hvals employee #所有值
1) "libai"
2) "22"
3) "man"
4) "123"
5) "14.8"
11 hlen 键数
- 格式:HLEN key
- 功能:返回哈希表 key 中域的数量
- 说明:当 key 不存在时,返回0
cmd
127.0.0.1:6379> hvals employee
1) "libai"
2) "22"
3) "man"
4) "123"
5) "14.8"
127.0.0.1:6379> hlen employee
(integer) 5
127.0.0.1:6379> hlen employee1
(integer) 0
127.0.0.1:6379>
12 hstrlen 值长度
- 格式:hstrlen key field
- 功能:返回哈希表 key 中,与给定域 field 相关联的值的字符串长度(string length)
- 说明:如果给定的键或者域不存在,那么返回0
cmd
127.0.0.1:6379> hlen employee
(integer) 5
127.0.0.1:6379> hlen employee1
(integer) 0
127.0.0.1:6379> hstrlen employee name
(integer) 5
127.0.0.1:6379> hstrlen employee1 name
(integer) 0
127.0.0.1:6379> hstrlen employee name1
(integer) 0
127.0.0.1:6379>
13 应用场景
Hash 型 Value 非常使用存储对象数据。key 为对象名称,value 为描述对象属性的 Map, 对对象属性的修改在 Redis 中就可直接完成。其不像 String 型 Value 存储对象,那个对象时序列化过的,例如序列化为 JSON 串,对对象属性值的修改需要先反序列化为对象后再修改,修改后再序列化为JSON 串后写入到 Redis
五 List型value操作命令
Redis 存储数据的 Value 可以是一个 String 列表类型数据。即该列表中的每个元素均为 String 类型数据。列表中的数据会按照插入顺序进行排序。不过,该列表的底层实际是一个无头节点的双向链表,所以对列表表头与表尾的操作性能较高,但对中间元素的插入与删除的操作的性能相对较差。
1 lpush/rpush 左右建值
- 格式:LPUSH key value [value ...] 或 RPUSH key value [value ...]
- 功能:将一个或多个值 value 插入到列表 key 的表头/表尾(表头在左表尾在右)
- 说明:如果有多个 value 值,对于 lpush 来说,各个 value 会按从左到右的顺序依次插入到表头;对于 rpush 来说,各个 value 会按从左到右的顺序依次插入到表尾。如果 key不存在,一个空列表会被创建并执行操作。当 key 存在但不是列表类型时,返回一个错误。执行成功时返回列表的长度。
cmd
127.0.0.1:6379> lpush ls 1 2 3 #1 2 3依次往左
(integer) 3
127.0.0.1:6379> lrange ls 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> rpush ls 4 5 6 #4 5 6依次往右
(integer) 6
127.0.0.1:6379> lrange ls 0 -1
1) "3"
2) "2"
3) "1"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379>
2 llen 长度
- 格式:LLEN key
- 功能:返回列表 key 的长度。
- 说明:如果 key 不存在,则 key 被解释为一个空列表,返回 0 。如果 key 不是列表类型,返回一个错误。
cmd
127.0.0.1:6379> llen ls #存在
(integer) 6
127.0.0.1:6379> llen lls #不存在
(integer) 0
127.0.0.1:6379>
3 lindex 对应下标值
- 格式:LINDEX key index
- 功能:返回列表 key 中,下标为 index 的元素。列表从 0 开始计数。
- 说明:如果 index 参数的值不在列表的区间范围内(out of range),返回 nil 。
cmd
127.0.0.1:6379> lrange ls 0 -1
1) "3"
2) "2"
3) "1"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> lindex ls 0 #第一个元素值
"3"
127.0.0.1:6379> lindex ls -1#最后一个元素值
"6"
127.0.0.1:6379> lindex ls 10
(nil)
4 lset 替换
- 格式:LSET key index value
- 功能:将列表 key 下标为 index 的元素的值设置为 value 。
- 说明:当 index 参数超出范围,或对一个空列表(key 不存在)进行 LSET 时,返回一个错误。
cmd
127.0.0.1:6379> lrange ls 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> lset ls 0 c
OK
127.0.0.1:6379> lrange ls 0 -1
1) "c"
2) "2"
3) "1"
127.0.0.1:6379> lset ls 10 aa
(error) ERR index out of range
5 lrange 返回区间
- 格式:LRANGE key start stop
- 功能:返回列表 key 中指定区间[start, stop]内的元素,即包含两个端点。
- 说明:List 的下标从 0 开始,即以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。超出范围的下标值不会引起错误。如果 start 下标比列表的最大下标 还要大,那么 LRANGE 返回一个空列表。如果 stop 下标比最大下标还要大,Redis 将 stop 的值设置为最大下标。
cmd
127.0.0.1:6379> lrange ls 0 -1 #第一到最后
1) "c"
2) "2"
3) "1"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> lrange ls 0 2 #第一到第三 0 1 2
1) "c"
2) "2"
3) "1"
127.0.0.1:6379> lrange ls -2 -1 #倒数第二 到 倒数第三
1) "5"
2) "6"
127.0.0.1:6379> lrange ls 1 10 #第一道到第十
1) "2"
2) "1"
3) "4"
4) "5"
5) "6"
127.0.0.1:6379>
6 lpushx/rpushx 最左右追加
- 格式:LPUSHX key value 或 RPUSHX key value
- 功能:将值 value 插入到列表 key 的表头/表尾,当且仅当 key 存在并且是一个列表。
- 说明:当 key 不存在时,命令什么也不做。若执行成功,则输出表的长度。
cmd
127.0.0.1:6379> lpushx ls 7 #最左追加 7 rpushx:最右追加
(integer) 7
127.0.0.1:6379> lpushx lls 7
(integer) 0
127.0.0.1:6379> lrange ls 0 -1
1) "7"
2) "c"
3) "2"
4) "1"
5) "4"
6) "5"
7) "6"
127.0.0.1:6379>
7 linsert 前后追加
- 格式:LINSERT key BEFORE|AFTER pivot value 【BEFORE前,AFTER后】
- 功能:将值 value 插入到列表 key 当中,位于元素 pivot 之前或之后。
- 说明:当 pivot 元素不存在于列表中时,不执行任何操作,返回-1;当 key 不存在时, key 被视为空列表,不执行任何操作,返回 0;如果 key 不是列表类型,返回一个错误;如果命令执行成功,返回插入操作完成之后,列表的长度。
cmd
127.0.0.1:6379> lpush nums 321
(integer) 1
127.0.0.1:6379> lpush nums 1 2 3
(integer) 4
127.0.0.1:6379> lrange nums 0 -1
1) "3"
2) "2"
3) "1"
4) "321"
127.0.0.1:6379> linsert nums before 3 4 #找值3 在之前 追加:4
(integer) 5
127.0.0.1:6379> lrange nums 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "321"
127.0.0.1:6379>
8 lpop/rpop 头尾移除
- 格式:LPOP key [count] 或 RPOP key [count]
- 功能:从列表 key 的表头/表尾移除 count 个元素,并返回移除的元素。count 默认值 1
- 说明:当 key 不存在时,返回 nil
cmd
127.0.0.1:6379> lrange nums 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "321"
127.0.0.1:6379> lpop nums 1 #移除最左元素 数量1,返回移除元素
1) "4"
127.0.0.1:6379> lrange nums 0 -1
1) "3"
2) "2"
3) "1"
4) "321"
127.0.0.1:6379> rpop nums 2 #移除最右元素 数量2 ,返回移除元素
1) "321"
2) "1"
127.0.0.1:6379> lrange nums 0 -1
1) "3"
2) "2"
127.0.0.1:6379>
9 blpop/brpop 没理解
- 格式:BLPOP key [key ...] timeout 或 BRPOP key [key ...] timeout
- 功能:BLPOP/BRPOP 是列表的阻塞式(blocking)弹出命令。它们是 LPOP/RPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP/BRPOP 命令阻塞,直到等待 timeout 超时或发现可弹出元素为止。当给定多个 key 参数时,按参数 key的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。timeout 为阻塞时长,单位为秒,其值若为 0,则表示只要没有可弹出元素,则一直阻塞。
- 说明:假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值。
cmd
10 rpoplpush 最左元素移动
- 格式:RPOPLPUSH source destination
- 功能:命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作:
- 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。
- 将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。如果 source 不存在【不变】,值 nil 被返回,并且不执行其他动作。如果 source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列 表的旋转(rotation)操作。
- 说明:
cmd
127.0.0.1:6379> lrange nums 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> rpoplpush nums nums #把nums【2】最左元素移到nums【1】最右
"1"
127.0.0.1:6379> lrange nums 0 -1
1) "1"
2) "4"
3) "3"
4) "2"
127.0.0.1:6379>
11 brpoplpush 没理解
- 格式:BRPOPLPUSH source destination timeout
- 功能:BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本,当给定列表 source 不为空时, BRPOPLPUSH 的表现和 RPOPLPUSH 一样。当列表 source 为空时, BRPOPLPUSH 命令将阻塞连接,直到等待超时,或有另一个客户端对 source 执行 LPUSH 或 RPUSH 命令为止。timeout 为阻塞时长,单位为秒,其值若为 0,则表示只要没有可弹出元素,则一直阻塞。
- 说明:假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。反之,返回一个含有两个元素的列表,第一个元素是被弹出元素的值,第二个元素是等待时长。
cmd
12 lrem 移除指定元素
- 格式:LREM key count value
- 功能:根据参数 count 的值,移除列表中与参数 value 相等的元素。count 的值可以是以下几种:
- count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
- count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
- count = 0 : 移除表中所有与 value 相等的值。
- 说明:返回被移除元素的数量。当 key 不存在时, LREM 命令返回 0 ,因为不存在的 key 被视作空表(empty list)。
cmd
127.0.0.1:6379> lrange nums 0 -1
1) "a"
2) "5"
3) "a"
4) "1"
5) "4"
6) "3"
7) "2"
8) "a"
127.0.0.1:6379> lrem nums 2 a #移除从左开始的两个a,返回移除的数量
(integer) 2
127.0.0.1:6379> lrange nums 0 -1
1) "5"
2) "1"
3) "4"
4) "3"
5) "2"
6) "a"
127.0.0.1:6379>lrem nums -2 a #列表尾部开始,移除最后 2 个值为 "a" 的元素(绝对值为 2)。
13 ltrim 修剪
- 格式:LTRIM key start stop
- 功能:对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
- 说明:下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。当 key 不是列表类型时,返回一个错误。如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,或者 start > stop , LTRIM 返回一个空列表,因为 LTRIM 已经将整个列表清空。如果 stop 下标比 end 下标还要大,Redis 将 stop 的值设置为 end 。
cmd
127.0.0.1:6379> lrange nums 0 -1
1) "5"
2) "1"
3) "4"
4) "3"
5) "2"
127.0.0.1:6379> ltrim nums 1 3 #保存下标 1 到 3 【负数就从后往前 如-1 就是最后一个】
OK
127.0.0.1:6379> lrange nums 0 -1
1) "1"
2) "4"
3) "3"
127.0.0.1:6379>
14 应用场景
Value 为 List 类型的应用场景很多,主要是通过构建不同的数据结构来实现相应的业务功能。这里仅对这些数据结构的实现方式进行总结,不举具体的例子。
(1)栈
通过 lpush + lpop 可以实现栈数据结构效果:先进后出。通过 lpush 从列表左侧插入数据,通过 lpop 从列表左侧取出数据。当然,通过 rpush + rpop 也可以实现相同效果,只不过操作的是列表右侧。
(2)队列
通过 lpush + rpop 可以实现队列数据结构效果:先进先出。通过 lpush 从列表左侧插入数据,通过 rpop 从列表右侧取出数据。当然,通过 rpush + lpop 也可以实现相同效果,只不过操作的方向正好相反。
(3)阻塞式消息队列
通过 lpush + brpop 可以实现阻塞式消息队列效果。作为消息生产者的客户端使用 lpush从列表左侧插入数据,作为消息消费者的多个客户端使用 brpop 阻塞式"抢占"列表尾部数据进行消费,保证了消费的负载均衡与高可用性。brpop 的 timeout 设置为 0,表示只要没有数据可弹出,就永久阻塞。
(4)动态有限集合
通过 lpush + ltrim 可以实现有限集合。通过lpush 从列表左侧向列表中添加数据,通过 ltrim 保持集合的动态有限性。像企业的末位淘汰、学校的重点班等动态管理,都可通过这种动态有限集合来实现。当然,通过rpush + ltrim 也可以实现相同效果,只不过操作的方向正好相反。
六 Set型value操作命令
Redis 存储数据的 Value 可以是一个 Set 集合,且集合中的每一个元素均 String 类型。Set与 List 非常相似,但不同之处是 Set 中的元素具有无序性与不可重复性,而 List 则具有有序性与可重复性。
Redis 中的 Set 集合与 Java 中的 Set 集合的实现相似,其底层都是value 为 null 的 hash表。也正因为此,才会引发无序性与不可重复性。
1 sadd 添加集合元素
- 格式:SADD key member [member ...]
- 功能:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member元素将被忽略。
- 说明:假如 key 不存在,则创建一个只包含 member 元素作成员的集合。当 key 不是集合类型时,返回一个错误。
cmd
127.0.0.1:6379> sadd st a b c #st 添加元素 a b c 【只能添加集合类型】
(integer) 3
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> sadd st b c d #b c已存在 只添加d
(integer) 1
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379>
2 smembers 返回集合元素
- 格式:SMEMBERS key
- 功能:返回集合 key 中的所有成员。
- 说明:不存在的 key 被视为空集合。若 key 中包含大量元素,则该命令可能会阻塞 Redis服务。所以生产环境中一般不使用该命令,而使用 sscan 命令代替。
cmd
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> smembers stt
(empty array)
127.0.0.1:6379>
3 scard 集合的长度
- 格式:SCARD key
- 功能:返回 Set 集合的长度
- 说明:当 key 不存在时,返回 0 。
cmd
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> scard st
(integer) 4
127.0.0.1:6379> scard stt
(integer) 0
127.0.0.1:6379>
4 sismenber 是否存在元素
- 格式:SISMEMBER key member
- 功能:判断 member 元素是否集合 key 的成员。
- 说明:如果 member 元素是集合的成员,返回 1 。如果 member 元素不是集合的成员,或 key 不存在,返回 0 。
cmd
127.0.0.1:6379> smembers st # 查看集合 st 的所有元素
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> sismember st a # 判断 "a" 是否是集合 st 的成员(是,返回1)
(integer) 1
127.0.0.1:6379> sismember st e # 判断 "e" 是否是集合 st 的成员(否,返回0)
(integer) 0
127.0.0.1:6379> sismember stt a # 判断 "a" 是否是不存在的集合 stt 的成员(key不存在,返回0)
(integer) 0
127.0.0.1:6379>
5 smove 集合移动
- 格式:SMOVE source destination member
- 功能:将 member 元素从 source 集合移动到 destination 集合。
- 说明:如果 source 集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回 0 。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去,返回 1。当 destination 集合已经包含 member 元素时, SMOVE命令只是简单地将 source 集合中的 member 元素删除。当 source 或 destination 不是集合类型时,返回一个错误。
cmd
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> smembers stt
1) "x"
2) "y"
3) "z"
127.0.0.1:6379> smove stt st x #把stt【集合】中x【元素x】 移动到 st中
(integer) 1
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
5) "x"
127.0.0.1:6379> smembers stt
1) "y"
2) "z"
127.0.0.1:6379> sadd stt x
(integer) 1
127.0.0.1:6379> smove stt st x #st中已存在x元素不变,stt的x元素移除
(integer) 1
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
5) "x"
127.0.0.1:6379> smembers stt
1) "y"
2) "z"
127.0.0.1:6379>
6 srem 移除
- 格式:SREM key member [member ...]
- 功能:移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略,且返回成功移除的元素个数。
- 说明:当 key 不是集合类型,返回一个错误。
cmd
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
5) "x"
127.0.0.1:6379> srem st d x #移除d x
(integer) 2
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> srem st c d e #集合中只有c 没用d e,只移除c返回1
(integer) 1
127.0.0.1:6379> smembers st
1) "a"
2) "b"
127.0.0.1:6379>
7 srandmenber 随机取
- 格式:SRANDMEMBER key [count]
- 功能:返回集合中的 count 个随机元素。count 默认值为 1。
- 说明:若 count 为正数,且小于集合长度,那么返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合长度,那么返回整个集合。如果count 为负数,那么返回一个包含 count 绝对值个元素的数组,但数组中的元素可能会出现重复。
cmd
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> srandmember st #默认随意1
"e"
127.0.0.1:6379> srandmember st 2 #固定随机数2
1) "a"
2) "b"
127.0.0.1:6379> srandmember st 5
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> srandmember st -4 #带负数随机数可重复
1) "c"
2) "e"
3) "c"
4) "d"
127.0.0.1:6379>
8 spop 随机移除元素
- 格式:SPOP key [count]
- 功能:移除并返回集合中的 count 个随机元素。count 必须为正数,且默认值为 1。
- 说明:如果 count 大于等于集合长度,那么移除并返回整个集合。【不能负数】
cmd
127.0.0.1:6379> smembers st
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> spop st #随意移除1,并返回移除元素
"e"
127.0.0.1:6379> spop st 2 #随意移除2,并返回移除元素
1) "a"
2) "c"
127.0.0.1:6379> smembers st
1) "b"
2) "d"
127.0.0.1:6379>
9 sdiff/sdiffstore 差集
- 格式:SDIFF key [key ...] 或 SDIFFSTORE destination key [key ...]
- 功能:返回第一个集合与其它集合之间的差集。差集,difference。
- 说明:这两个命令的不同之处在于,sdiffstore 不仅能够显示差集,还能将差集存储到指定的集合 destination 中。如果 destination 集合已经存在,则将其覆盖。不存在的 key 被视为空集。
cmd
# 准备三个集合,添加元素
127.0.0.1:6379> sadd set1 a b c d
(integer) 4
127.0.0.1:6379> sadd set2 c d e f
(integer) 4
127.0.0.1:6379> sadd set3 d e g
(integer) 3
# 查看集合内容
127.0.0.1:6379> smembers set1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> smembers set2
1) "c"
2) "d"
3) "e"
4) "f"
127.0.0.1:6379> smembers set3
1) "d"
2) "e"
3) "g"
# 场景1:SDIFF 计算第一个集合与单个集合的差集
# set1 与 set2 的差集:仅在 set1 中存在,不在 set2 中的元素
127.0.0.1:6379> sdiff set1 set2
1) "a"
2) "b" # set1中的a、b不在set2中,c、d在set2中,故差集为a、b
# 场景2:SDIFF 计算第一个集合与多个集合的差集
# set1 与 set2、set3 的差集:仅在 set1 中,且不在 set2 和 set3 中的元素
127.0.0.1:6379> sdiff set1 set2 set3
1) "a"
2) "b" # set1中的c在set2中,d在set2和set3中,故差集仍为a、b
# 场景3:差集顺序影响结果(第一个集合不同,结果不同)
# set2 与 set1 的差集:仅在 set2 中,不在 set1 中的元素
127.0.0.1:6379> sdiff set2 set1
1) "e"
2) "f" # set2中的e、f不在set1中,c、d在set1中,故差集为e、f
# 场景4:处理不存在的key(视为空集)
# set1 与不存在的 set4(空集)的差集:set1 所有元素(因空集无元素)
127.0.0.1:6379> sdiff set1 set4
1) "a"
2) "b"
3) "c"
4) "d"
# 场景5:SDIFFSTORE 将差集存储到指定集合
# 将 set1 与 set2 的差集存储到 diff_set
127.0.0.1:6379> sdiffstore diff_set set1 set2
(integer) 2 # 返回差集中的元素数量(2个:a、b)
# 查看存储的差集
127.0.0.1:6379> smembers diff_set
1) "a"
2) "b"
# 场景6:SDIFFSTORE 覆盖已存在的集合
# 先向 diff_set 添加新元素
127.0.0.1:6379> sadd diff_set x y
(integer) 2
127.0.0.1:6379> smembers diff_set
1) "a"
2) "b"
3) "x"
4) "y"
# 用新的差集(set2 与 set3)覆盖 diff_set
127.0.0.1:6379> sdiffstore diff_set set2 set3
(integer) 2 # set2与set3的差集是c、f(共2个)
# 查看覆盖后的结果(原元素被替换)
127.0.0.1:6379> smembers diff_set
1) "c"
2) "f"
10 sinter/sinterstore 交集
- 格式:SINTER key [key ...] 或 SINTERSTORE destination key [key ...]
- 功能:返回多个集合间的交集。交集,intersection。
- 说明:这两个命令的不同之处在于,sinterstore 不仅能够显示交集,还能将交集存储到指定的集合 destination 中。如果 destination 集合已经存在,则将其覆盖。不存在的 key被视为空集。
cmd
# 准备三个集合,添加元素
127.0.0.1:6379> sadd setA a b c d e
(integer) 5
127.0.0.1:6379> sadd setB c d e f g
(integer) 5
127.0.0.1:6379> sadd setC d e f h
(integer) 4
# 查看集合内容
127.0.0.1:6379> smembers setA
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> smembers setB
1) "c"
2) "d"
3) "e"
4) "f"
5) "g"
127.0.0.1:6379> smembers setC
1) "d"
2) "e"
3) "f"
4) "h"
# 场景1:SINTER 计算两个集合的交集
# setA 和 setB 的交集:同时存在于两个集合中的元素
127.0.0.1:6379> sinter setA setB
1) "c"
2) "d"
3) "e" # 元素c、d、e在setA和setB中均存在
# 场景2:SINTER 计算多个集合的交集
# setA、setB、setC 的交集:同时存在于三个集合中的元素
127.0.0.1:6379> sinter setA setB setC
1) "d"
2) "e" # 仅d、e同时存在于三个集合中(c不在setC,f不在setA)
# 场景3:处理不存在的key(视为空集)
# setA 与不存在的 setX(空集)的交集:空集(因空集与任何集合交集为空)
127.0.0.1:6379> sinter setA setX
(empty array)
# 场景4:SINTERSTORE 将交集存储到指定集合
# 将 setA 和 setB 的交集存储到 inter_set
127.0.0.1:6379> sinterstore inter_set setA setB
(integer) 3 # 返回交集中的元素数量(3个:c、d、e)
# 查看存储的交集
127.0.0.1:6379> smembers inter_set
1) "c"
2) "d"
3) "e"
# 场景5:SINTERSTORE 覆盖已存在的集合
# 先向 inter_set 添加新元素
127.0.0.1:6379> sadd inter_set x y
(integer) 2
127.0.0.1:6379> smembers inter_set
1) "c"
2) "d"
3) "e"
4) "x"
5) "y"
# 用新的交集(setB 和 setC)覆盖 inter_set
127.0.0.1:6379> sinterstore inter_set setB setC
(integer) 3 # setB与setC的交集是d、e、f(共3个)
# 查看覆盖后的结果(原元素被替换)
127.0.0.1:6379> smembers inter_set
1) "d"
2) "e"
3) "f"
11 sunion/sunionstore 并集
- 格式:SUNION key [key ...] 或 SUNIONSTORE destination key [key ...]
- 功能:返回多个集合间的并集。并集,union。
- 说明:这两个命令的不同之处在于,sunionstore 不仅能够显示并集,还能将并集存储到指定的集合 destination 中。如果 destination 集合已经存在,则将其覆盖。不存在的 key被视为空集。
cmd
# 准备三个集合,添加元素(包含重叠和独有元素)
127.0.0.1:6379> sadd setX 1 2 3 4
(integer) 4
127.0.0.1:6379> sadd setY 3 4 5 6
(integer) 4
127.0.0.1:6379> sadd setZ 5 6 7 8
(integer) 4
# 查看集合内容
127.0.0.1:6379> smembers setX
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> smembers setY
1) "3"
2) "4"
3) "5"
4) "6"
127.0.0.1:6379> smembers setZ
1) "5"
2) "6"
3) "7"
4) "8"
# 场景1:SUNION 计算两个集合的并集
# setX 和 setY 的并集:包含两个集合的所有元素(去重)
127.0.0.1:6379> sunion setX setY
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6" # 合并后包含setX的1、2和setY的5、6,以及共有的3、4(无重复)
# 场景2:SUNION 计算多个集合的并集
# setX、setY、setZ 的并集:包含三个集合的所有元素(去重)
127.0.0.1:6379> sunion setX setY setZ
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8" # 合并三个集合的所有元素,无重复
# 场景3:处理不存在的key(视为空集)
# setX 与不存在的 setEmpty(空集)的并集:等同于setX本身(空集无元素可添加)
127.0.0.1:6379> sunion setX setEmpty
1) "1"
2) "2"
3) "3"
4) "4"
# 场景4:SUNIONSTORE 将并集存储到指定集合
# 将 setX 和 setY 的并集存储到 union_set
127.0.0.1:6379> sunionstore union_set setX setY
(integer) 6 # 返回并集中的元素数量(6个)
# 查看存储的并集
127.0.0.1:6379> smembers union_set
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
# 场景5:SUNIONSTORE 覆盖已存在的集合
# 先向 union_set 添加新元素
127.0.0.1:6379> sadd union_set 9 10
(integer) 2
127.0.0.1:6379> smembers union_set
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "9"
8) "10"
# 用新的并集(setY 和 setZ)覆盖 union_set
127.0.0.1:6379> sunionstore union_set setY setZ
(integer) 6 # setY与setZ的并集是3、4、5、6、7、8(共6个)
# 查看覆盖后的结果(原元素被替换)
127.0.0.1:6379> smembers union_set
1) "3"
2) "4"
3) "5"
4) "6"
5) "7"
6) "8"
12 应用场景
1)动态黑名单
例如某服务器中要设置用于访问控制的黑名单。如果直接将黑名单写入服务器的配置文件,那么存在的问题是,无法动态修改黑名单。此时可以将黑名单直接写入Redis,只要有客户端来访问服务器,服务器在获取到客户端IP 后先从Redis 的黑名单中查看是否存在该IP,如果存在,则拒绝访问,否则访问通过。
(2)有限随机数
有限随机数是指返回的随机数是基于某一集合范围内的随机数,例如抽奖、随机选人。通过 spop 或 srandmember 可以实现从指定集合中随机选出元素。
(3)用户画像
社交平台、电商平台等各种需要用户注册登录的平台,会根据用户提供的资料与用户使用习惯,为每个用户进行画像,即为每个用户定义很多可以反映该用户特征的标签,这些标签就可以使用sadd 添加到该用户对应的集合中。这些标签具有无序、不重复特征。
同时平台还可以使用 sinter/sinterstore 根据用户画像间的交集进行好友推荐、商品推荐、客户推荐等。
七 有序Set型value操作命令
1 zadd 添加
- 格式:ZADD key score member 【【score member】【score member】 ...】
- 功能:将一个或多个 member 元素及其 score 值加入到有序集 key 中的适当位置。
- 说明:score 值可以是整数值或双精度浮点数 。如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。当 key 存在但不是有序集类型时,返回一个错误。如果命令执行成功,则返回被成功添加 的新成员的数量,不包括那些被更新的、已经存在的成员。若写入的 member 值已经存在,但score 值不同,则新的 score 值将覆盖老 score。
cmd
# 场景1:向空有序集添加多个新成员(key不存在时自动创建)
# 向有序集 "student_scores" 添加成员,分数为整数或浮点数
127.0.0.1:6379> zadd student_scores 90 alice 85 bob 95 charlie 88.5 dave
(integer) 4 # 返回4,表示4个均为新成员
# 查看有序集(按分数升序,带分数)
127.0.0.1:6379> zrange student_scores 0 -1 withscores
1) "bob"
2) "85"
3) "dave"
4) "88.5"
5) "alice"
6) "90"
7) "charlie"
8) "95"
# 场景2:添加已存在的成员(更新分数,不计数)
# 尝试添加已存在的 "bob",更新分数为87
127.0.0.1:6379> zadd student_scores 87 bob
(integer) 0 # 返回0,因为"bob"已存在(仅更新分数,不算新成员)
# 查看更新后:bob的分数从85变为87
127.0.0.1:6379> zrange student_scores 0 -1 withscores
1) "dave"
2) "88.5"
3) "bob"
4) "87" # 分数已更新
5) "alice"
6) "90"
7) "charlie"
8) "95"
# 场景3:同时添加新成员和已有成员(仅新成员计数)
# 添加新成员 "eve"(分数79)和已有成员 "alice"(更新为92)
127.0.0.1:6379> zadd student_scores 92 alice 79 eve
(integer) 1 # 返回1,仅"eve"是新成员
# 查看结果:alice分数更新,eve新增
127.0.0.1:6379> zrange student_scores 0 -1 withscores
1) "eve"
2) "79"
3) "dave"
4) "88.5"
5) "bob"
6) "87"
7) "alice"
8) "92" # 分数更新
9) "charlie"
10) "95"
# 场景4:key不是有序集类型(返回错误)
# 创建字符串类型的key "str_key"
127.0.0.1:6379> set str_key "not a zset"
OK
# 尝试向非有序集key执行ZADD
127.0.0.1:6379> zadd str_key 100 test
(error) WRONGTYPE Operation against a key holding the wrong kind of value
2 zrange/zrevrange
-
格式:ZRANGE key start stop [WITHSCORES] 或 ZREVRANGE key start stop [WITHSCORES]
-
功能:返回有序集 key 中,指定区间内的成员。zrange 命令会按 score 值递增排序, zrevrange 命令会按score 递减排序。具有相同 score 值的成员按字典序/逆字典序排列。可以通过使用 WITHSCORES 选项,来让成员和它的 score 值一并返回。
说明:下标参数从 0 开始,即 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。也可以使用负数下标,-1 表示最后一个成员,-2 表示倒数第二个成员,以此类推。超出范围的下标并不会引起错误。例如,当 start 的值比有序集的最大下标还要大,或是 start > stop 时, ZRANGE 命令只是简单地返回一个空列表。再比如 stop 参数的值比有序集的最大下标还要大,那么 Redis 将 stop 当作最大下标来处理。
若 key 中指定范围内包含大量元素,则该命令可能会阻塞 Redis 服务。所以生产环境中如果要查询有序集合中的所有元素,一般不使用该命令,而使用 zscan 命令代替。
cmd
3 zrangebyscore/zrevrangebyscore
-
格式:ZRANGEBYSCORE key min max 【WITHSCORES】【LIMIT offset count】 ZREVRANGEBYSCORE key max min 【WITHSCORES】【LIMIT offset count】
-
功能:返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增/递减次序排列。具有相同 score 值的成员按字典序/逆字典序排列。可选的 LIMIT 参数指定返回结果的数量及区间(就像 SQL 中的 SELECT LIMIT offset, count ),注意当 offset 很大时,定位 offset 的操作可能需要遍历整个有序集,此过程效率可能会较低。可选的 WITHSCORES 参数决定结果集是单单返回有序集的成员,还是将有序集成员及其 score 值一起返回。
-
说明:min 和 max 的取值是正负无穷大的。默认情况下,区间的取值使用闭区间 (小于等于或大于等于),也可以通过给参数前增加左括号"("来使用可选的开区间 (小于或大于)。
cmd
4 zcard
- 格式:ZCARD key
- 功能:返回集合的长度
- 说明:当 key 不存在时,返回 0 。
cmd
5 zcount
- 格式:ZCOUNT key min max
- 功能:返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min或 max )的成员的数量。
cmd
6 zscore
- 格式:ZSCORE key member
- 功能:返回有序集 key 中,成员 member 的 score 值。
- 说明:如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。
cmd
7 zincrby
-
格式:ZINCRBY key increment member
-
功能:为有序集 key 的成员 member 的 score 值加上增量 increment 。increment 值可以是整数值或双精度浮点数。
-
说明:可以通过传递一个负数值 increment ,让 score 减去相应的值。当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。当 key 不是有序集类型时,返回一个错误。命令执行成功,则返回 member 成员的新 score 值。
cmd
8 zrank/zrevrank
- 格式:ZRANK key member 或 ZREVRANK key member
- 功能:返回有序集 key 中成员 member 的排名。zrank 命令会按 score 值递增排序,zrevrank 命令会按 score 递减排序。
- 说明:score 值最小的成员排名为 0 。如果 member 不是有序集 key 的成员,返回 nil 。
cmd
9 zrem
- 格式:ZREM key member [member ...]
- 功能:移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。
- 说明:当 key 存在但不是有序集类型时,返回一个错误。执行成功,则返回被成功移除的成员的数量,不包括被忽略的成员。
cmd
10 zremrangebyrank
-
格式:ZREMRANGEBYRANK key start stop
-
功能:移除有序集 key 中,指定排名(rank)区间内的所有成员。
-
说明:排名区间分别以下标参数 start 和 stop 指出,包含 start 和 stop 在内。排名区间参数从 0 开始,即 0 表示排名第一的成员, 1 表示排名第二的成员,以此类推。也可以使用负数表示,-1 表示最后一个成员,-2 表示倒数第二个成员,以此类推。命令执行成功,则返回被移除成员的数量。
cmd
11 zremrangebyscore
- 格式:ZREMRANGEBYSCORE key min max
- 功能:移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或max )的成员。
- 说明:命令执行成功,则返回被移除成员的数量。
cmd
12 zrangebylex
-
格式:ZRANGEBYLEX key min max [LIMIT offset count]
-
功能:该命令仅适用于集合中所有成员都具有相同分值的情况。当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的字典序(lexicographical ordering)来进行排序。即这个命令返回给定集合中元素值介于 min 和 max 之间的成员。如果有序集合里面的成员带有不同的分值, 那么命令的执行结果与 zrange key 效果相同。
-
说明:合法的 min 和 max 参数必须包含左小括号"("或左中括号"[",其中左小括号"("表示开区间, 而左中括号"["则表示闭区间。min 或max 也可使用特殊字符"+"和"-",分别表示正无穷大与负无穷大。
cmd
13 zlexcount
- 格式:ZLEXCOUNT key min max
- 功能:该命令仅适用于集合中所有成员都具有相同分值的情况。该命令返回该集合中元素值本身(而非score 值)介于 min 和 max 范围内的元素数量。
cmd
14 zremrangebylex
- 格式:ZREMRANGEBYLEX key min max
- 功能:该命令仅适用于集合中所有成员都具有相同分值的情况。该命令会移除该集合中元素值本身介于 min 和 max 范围内的所有元素。
cmd
15 应用场景
有序 Set 最为典型的应用场景就是排行榜,例如音乐、视频平台中根据播放量进行排序的排行榜;电商平台根据用户评价或销售量进行排序的排行榜等。将播放量作为 score,将作品 id 作为 member,将用户评价积分或销售量作为 score,将商家 id 作为member。使用 zincrby 增加排序 score,使用 zrevrange 获取 Top 前几名,使用 zrevrank 查询当前排名,使用 zscore 查询当前排序score 等。
t 值可以是整数值或双精度浮点数。
- 说明:可以通过传递一个负数值 increment ,让 score 减去相应的值。当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。当 key 不是有序集类型时,返回一个错误。命令执行成功,则返回 member 成员的新 score 值。
cmd
8 zrank/zrevrank
- 格式:ZRANK key member 或 ZREVRANK key member
- 功能:返回有序集 key 中成员 member 的排名。zrank 命令会按 score 值递增排序,zrevrank 命令会按 score 递减排序。
- 说明:score 值最小的成员排名为 0 。如果 member 不是有序集 key 的成员,返回 nil 。
cmd
9 zrem
- 格式:ZREM key member [member ...]
- 功能:移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。
- 说明:当 key 存在但不是有序集类型时,返回一个错误。执行成功,则返回被成功移除的成员的数量,不包括被忽略的成员。
cmd
10 zremrangebyrank
-
格式:ZREMRANGEBYRANK key start stop
-
功能:移除有序集 key 中,指定排名(rank)区间内的所有成员。
-
说明:排名区间分别以下标参数 start 和 stop 指出,包含 start 和 stop 在内。排名区间参数从 0 开始,即 0 表示排名第一的成员, 1 表示排名第二的成员,以此类推。也可以使用负数表示,-1 表示最后一个成员,-2 表示倒数第二个成员,以此类推。命令执行成功,则返回被移除成员的数量。
cmd
11 zremrangebyscore
- 格式:ZREMRANGEBYSCORE key min max
- 功能:移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或max )的成员。
- 说明:命令执行成功,则返回被移除成员的数量。
cmd
12 zrangebylex
-
格式:ZRANGEBYLEX key min max [LIMIT offset count]
-
功能:该命令仅适用于集合中所有成员都具有相同分值的情况。当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的字典序(lexicographical ordering)来进行排序。即这个命令返回给定集合中元素值介于 min 和 max 之间的成员。如果有序集合里面的成员带有不同的分值, 那么命令的执行结果与 zrange key 效果相同。
-
说明:合法的 min 和 max 参数必须包含左小括号"("或左中括号"[",其中左小括号"("表示开区间, 而左中括号"["则表示闭区间。min 或max 也可使用特殊字符"+"和"-",分别表示正无穷大与负无穷大。
cmd
13 zlexcount
- 格式:ZLEXCOUNT key min max
- 功能:该命令仅适用于集合中所有成员都具有相同分值的情况。该命令返回该集合中元素值本身(而非score 值)介于 min 和 max 范围内的元素数量。
cmd
14 zremrangebylex
- 格式:ZREMRANGEBYLEX key min max
- 功能:该命令仅适用于集合中所有成员都具有相同分值的情况。该命令会移除该集合中元素值本身介于 min 和 max 范围内的所有元素。
cmd
15 应用场景
有序 Set 最为典型的应用场景就是排行榜,例如音乐、视频平台中根据播放量进行排序的排行榜;电商平台根据用户评价或销售量进行排序的排行榜等。将播放量作为 score,将作品 id 作为 member,将用户评价积分或销售量作为 score,将商家 id 作为member。使用 zincrby 增加排序 score,使用 zrevrange 获取 Top 前几名,使用 zrevrank 查询当前排名,使用 zscore 查询当前排序score 等。
原文链接:https://blog.csdn.net/m0_47015897/article/details/130045912