瑞_Redis_Redis命令
文章目录
- 1 Redis命令
- Redis数据结构
- Redis 的 key 的层级结构
- 1.0 Redis通用命令
- 1.0.1 KEYS
- 1.0.2 DEL
- 1.0.3 EXISTS
- 1.0.4 EXPIRE
- 1.0.5 TTL
- 1.1 String类型
- 1.1.0 String类型的常见命令
- 1.1.1 SET 和 GET
- 1.1.2 MSET 和 MGET
- 1.1.3 INCR和INCRBY和DECY
- 1.1.4 SETNX
- 1.1.5 SETEX
- 1.2 Hash类型
- 1.2.0 Hash类型的常见命令
- 1.2.1 HSET 和 HGET
- 1.2.2 HMSET 和 HMGET
- 1.2.3 HGETALL
- 1.2.4 HKEYS 和 HVALS
- 1.2.5 HINCRBY
- 1.2.6 HSETNX
- 1.3 List类型
- 1.3.0 List类型的常见命令
- 1.3.1 LPUSH 和 RPUSH
- 1.3.2 LPOP 和 RPOP
- 1.3.3 LRANGE
- 1.3.4 BLPOP 和 BRPOP
- 1.4 Set类型
- 1.4.0 Set类型的常见命令
- 1.4.1 Set中对单个集合的操作命令
- 1.4.2 Set中对多个集合的操作命令
- 1.4.3 Set命令练习
- 1.5 SortedSet类型
- 1.5.0 SortedSet类型的常见命令
- 1.5.1 SortedSet命令练习
🙊 前言:本文章为瑞_系列专栏之《Redis》的基础篇的Redis命令章节。由于博主是从B站黑马程序员的《Redis》学习其相关知识,所以本系列专栏主要是针对该课程进行笔记总结和拓展,文中的部分原理及图解等也是来源于黑马提供的资料,特此注明。本文仅供大家交流、学习及研究使用,禁止用于商业用途,违者必究!
主机操作系统:Windows10
VMware版本: VMware Workstation 16.2.4
Linux版本:CentOS 7 64位
远程连接工具:MobaXterm_Personal_23.2
Redis版本:redis-6.2.6.tar.gz
Redis客户端:resp-2022.2.0.0
相关链接:《瑞_VMware虚拟机安装Linux纯净版(含卸载,图文超详细)》
相关链接:《瑞_Redis_初识Redis(含安装教程)》
相关链接:《瑞_Redis_Redis客户端》
1 Redis命令
Redis官方为了方便我们学习,将操作不同数据类型的命令也做了分组,在官网( https://redis.io/commands )可以查看到不同的命令
Redis的命令行客户端接受的指令是不区分大小写的,这意味着无论你输入的是大写还是小写字母,Redis都会识别并执行相同的操作。例如,SET、set和SeT都会被当作是设置键值对的命令。
然而,需要注意的是,虽然Redis的指令本身不区分大小写,但Redis的键(key)是严格区分大小写的。如果你尝试使用相同的键但是大小写不同,Redis会将它们视为两个完全不同的键。
瑞:说明:本文中出现的
#
统一代表注释的意义,是为了图文讲解更加清晰,并非在代码中能够起到注释的作用,特此说明
Redis数据结构
Redis是典型的key-value数据库,key一般是字符串,而value包含很多不同的数据类型:
数据类型 | 示例 | 说明 | 备注 |
---|---|---|---|
String | hello world | 基本类型 | 普通字符串 |
Hash | {“name”: “Jack”, age: 21} | 基本类型 | 字符串描述 (本质是Hash表) |
List | [A -> B -> C -> C] | 基本类型 | 有序集合,本质是链表 |
Set | {A, B, C} | 基本类型 | 无需集合,元素不能重复 |
SortedSet | {A: 1, B: 2, C: 3} | 基本类型 | 有序集合,元素不能重复 |
GEO | {A: (119.3, 48.6} | 特殊类型 | 地理坐标(经纬度) |
BitMap | 0110110101110101011 | 特殊类型 | 特殊统计 |
HyperLog | 0110110101110101011 | 特殊类型 | 特殊统计 |
不同类型的命令称为一个group,我们也可以通过help命令来查看各种不同group的命令:
Redis 的 key 的层级结构
Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?
例如,需要存储用户、商品信息到redis,有一个用户id是1,有一个商品id恰好也是1,此时如果使用id作为key,那就会冲突了,该怎么办?
我们可以通过给key添加前缀加以区分,不过这个前缀不是随便加的,有一定的规范:
Redis的key允许有多个单词形成层级结构,多个单词之间用':'
隔开,如下示例⬇️
这个格式并非固定,也可以根据自己的需求来删除或添加词条。
例如我们的项目名称叫 heima,有user和product两种不同类型的数据,我们可以这样定义key:
- user相关的key:heima:user:1
- product相关的key:heima:product:1
如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:
KEY | VALUE |
---|---|
heima:user:1 | {“id”:1, “name”: “Jack”, “age”: 21} |
heima:product:1 | {“id”:1, “name”: “小米11”, “price”: 4999} |
一旦我们向redis采用这样的方式存储,那么在可视化界面中,redis会以层级结构来进行存储,形成类似于这样的结构,更加方便Redis获取数据
如执行以下命令
127.0.0.1:6379> set heima:user:1 '{"id":1, "name":"Jack", "age": 21}'
127.0.0.1:6379> set heima:user:2 '{"id":2, "name":"Rose", "age": 18}'
127.0.0.1:6379> set heima:product:1 '{"id":1, "name":"小米11", "price": 4999}'
127.0.0.1:6379> set heima:product:2 '{"id":2, "name":"荣耀6", "price": 2999}'
使用Redis客户端图形界面查看,发现自动分出了层级关系,这样就非常清晰
瑞:Redis客户端相关知识推荐:《瑞_Redis_Redis客户端》
1.0 Redis通用命令
查看通用命令:
help @generic
通用指令是部分数据类型的,都可以使用的指令,常见的有:
- KEYS:查看符合模板的所有key,不建议在生产环境设备上使用
- DEL:删除一个指定的key
- EXISTS:判断key是否存在
- EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
- TTL:查看一个KEY的剩余有效期
通过help [command] 可以查看一个命令的具体用法,例如:
# 查看keys命令的帮助信息:
127.0.0.1:6379> help keysKEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
group: generic
1.0.1 KEYS
- KEYS:查看符合模板的所有key,不建议在生产环境设备上使用
瑞:不要在主节点上使用该命令,容易造成阻塞。尤其是数据量大的时候,千万不要用
KEYS *
,*使用了模糊匹配查询的机制,效率很低,而Redis执行命令是单线程的,最终导致Redis服务阻塞
语法:
keys pattern
用法如下
# 数据准备
## 创建一个名为"name"的键,并将其值设置为"ray"
set name ray
## 创建一个名为"age"的键,并将其值设置为21
set age 21# keys 命令
## 这个命令将返回数据库中所有键的列表
keys *
## 这个命令将返回所有以"a"开头的键的列表
keys a*
## 这个命令将返回名为"name"的键的列表
keys name
1.0.2 DEL
- DEL:删除一个指定的key
语法:
del key [key ...]
用法如下
# 删除名为"name"的键(单个)
127.0.0.1:6379> del name
(integer) 1 #成功删除1个
127.0.0.1:6379> keys *
1) "age"
# 一次性批量设置多个键值对,分别是k1-v1、k2-v2和k3-v3
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "k3"
2) "age"
3) "k2"
4) "k1"
# 删除名为"k1"、"k2"、"k3"和"k4"的四个键
127.0.0.1:6379> del k1 k2 k3 k4
# 由于没有k4,所以返回的删除个数,3个建被删除
(integer) 3 #此处返回的是成功删除的key,由于redis中只有k1,k2,k3 所以只成功删除3个,最终返回
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379>
1.0.3 EXISTS
- EXISTS:判断key是否存在
语法:
exists key [key ...]
用法如下
# 判断键"age"是否存在
127.0.0.1:6379> exists age
# 存在,返回1
(integer) 1
# 判断键"name"是否存在
127.0.0.1:6379> exists name
# 不存在,返回0
(integer) 0
127.0.0.1:6379>
1.0.4 EXPIRE
- EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
语法:
expire key seconds
瑞:在实际开发中EXPIRE命令常和TTL命令一起使用。常见业务需求:如短信验证码的有效期5分钟。由于内存非常宝贵,所以对于一些数据,我们应当给他一些过期时间,当过期时间到了之后,就会自动被删除
用法如下
# 设置键"age"的有效期为20秒
127.0.0.1:6379> expire age 20
# 设置成功返回1,不成功返回0
(integer) 1
1.0.5 TTL
- TTL:查看一个KEY的剩余有效期
语法:
ttl key
瑞:TTL(Time To Leave)剩余生存时间
用法如下
# 设置键"age"的有效期为20秒
127.0.0.1:6379> expire age 20
# 查看键"age"的剩余有效期
127.0.0.1:6379> ttl age
# 大于0则返回当前该键的剩余有效期
(integer) 16
127.0.0.1:6379> ttl age
# 返回-2则表示该键已经被移除
(integer) -2
瑞:在Redis中存放数据的时候最好都设置一个有效期
1️⃣ 如果是expire
命令设置键的有效期,使用ttl
命令查看该键的时候,如果存在则返回该键的剩余有效期,如果不存在则返回-2(-2代表该键被移除)。
2️⃣ 如果只是set
命令设置的键并且没有使用expire
命令设置键的有效期,使用ttl
命令查看该键的时候则返回-1(-1代表改键永久有效)。
1.1 String类型
String类型,也就是字符串类型,是Redis中最简单的存储类型。其value是字符串,不过根据字符串的格式不同,又可以分为3类:
1️⃣ string:普通字符串
2️⃣ int:整数类型,可以做自增/自减操作
3️⃣ float:浮点类型,可以做自增/自减操作
KEY | VALUE |
---|---|
msg | hello world |
num | 10 |
score | 92.5 |
不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m
1.1.0 String类型的常见命令
- SET:添加或者修改已经存在的一个String类型的键值对
- GET:根据key获取String类型的value
- MSET:批量添加多个String类型的键值对
- MGET:根据多个key获取多个String类型的value
- INCR:让一个整型的key自增1
- INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2
- INCRBYFLOAT:让一个浮点类型的数字自增并指定步长
- SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行
- SETEX:添加一个String类型的键值对,并且指定有效期
瑞:以上命令除了INCRBYFLOAT 都是常用命令
1.1.1 SET 和 GET
- SET:添加或者修改已经存在的一个String类型的键值对(如果key不存在则是新增,如果存在则是修改)
语法:
set key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL]
- GET:根据key获取String类型的value
语法:
get key
用法如下
127.0.0.1:6379> keys *
(empty array) # 此时无数据
127.0.0.1:6379> set name Rose # 原来不存在"name"键,所以为新增操作
OK
127.0.0.1:6379> get name
"Rose" # 验证结果
127.0.0.1:6379> set name Jack # 已存在"name",所以为修改,将"Rose"改为"Jack"
OK
127.0.0.1:6379> get name
"Jack" # 验证结果
127.0.0.1:6379>
1.1.2 MSET 和 MGET
- MSET:批量添加多个String类型的键值对
语法:
mset key value [key value ...]
- MGET:根据多个key获取多个String类型的value
语法:
mget key [key ...]
用法如下
# 一次性批量设置多个键值对,分别是k1-v1、k2-v2和k3-v3
127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> MGET name age k1 k2 k3
1) "Jack"
2) (nil) # 不存在key-age
3) "v1"
4) "v2"
5) "v3"
1.1.3 INCR和INCRBY和DECY
- INCR:让一个整型的key自增1
语法:
incr key
- INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2
语法:
incrby key increment
- INCRBYFLOAT:让一个浮点类型的数字自增并指定步长
语法:
incrbyfloat key increment
瑞:浮点型自增必须要指定步长。由于INCRBY 能够实现减操作,所以一般 DECR和DECRBY 命令是用 INCRBY 命令代替。
用法如下
# 准备一个整形的key
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> get age
"18"
127.0.0.1:6379> incr age # 执行自增
(integer) 19
127.0.0.1:6379> incr age
(integer) 20
127.0.0.1:6379> incr age
(integer) 21
127.0.0.1:6379> incrby age 2 # 执行自增,指定步长为2
(integer) 23
127.0.0.1:6379> incrby age -1 # 执行自增,指定步长为-1,相当于减
(integer) 22
127.0.0.1:6379> set score 10.0 # 准备一个浮点型的key
OK
127.0.0.1:6379> incrbyfloat score 0.6 # 让浮点型自增,步长为0.5
"10.6"
127.0.0.1:6379> incrbyfloat score 0.6
"11.2"
127.0.0.1:6379>
1.1.4 SETNX
- SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行
语法:
setnx key value
瑞:真正的新增。
setnx
其实是组合命令,setnx key value
相当于set key value nx
用法如下
# 官方介绍
127.0.0.1:6379> help SETNXSETNX key valuesummary: Set the value of a key, only if the key does not existsince: 1.0.0group: string# 当前数据
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
4) "name"
5) "age"
6) "score"
127.0.0.1:6379> setnx name ray # 尝试添加已存在的key-name
(integer) 0 # 返回0,表示添加失败
127.0.0.1:6379> get name
"Jack" # key-name仍然存储原来的value-Jack
127.0.0.1:6379> setnx name2 ray # 尝试添加不存在的key-name2
(integer) 1 # 添加成功
127.0.0.1:6379> get name2
"ray"
127.0.0.1:6379> set name wangwu nx # setnx相当于set key value nx
(nil) # 添加失败
127.0.0.1:6379> get name
"Jack"
127.0.0.1:6379> set name3 wangwu nx # setnx相当于set key value nx
OK # 添加成功
127.0.0.1:6379> get name3
"wangwu"
127.0.0.1:6379>
1.1.5 SETEX
- SETEX:添加或修改一个String类型的键值对,并且指定有效期
语法:
setex key seconds value
瑞:
SETEX
是组合命令,相当于set key value
加expire key seconds
命令的组合执行结果。
即setex key seconds value
相当于set key value ex seconds
用法如下
# 官方介绍
127.0.0.1:6379> help setexSETEX key seconds valuesummary: Set the value and expiration of a keysince: 2.0.0group: string
# 此时存在key-name存储value-Jack
127.0.0.1:6379> keys *
1) "name2"
2) "k3"
3) "k2"
4) "k1"
5) "name"
6) "name3"
7) "score"
127.0.0.1:6379> setex name 10 ray # 添加或修改(此处为修改)一个String类型的键值对name-ray,并且指定有效期10秒
OK
127.0.0.1:6379> ttl name
(integer) 8
127.0.0.1:6379> get name
"ray" # 确定name的value被修改为ray
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) -2 # 此时过期
127.0.0.1:6379> keys * # 不存在name
1) "name2"
2) "k3"
3) "k2"
4) "k1"
5) "name3"
6) "score"
# 以下验证`setex key seconds value`相当于`set key value ex seconds`,相同的操作
127.0.0.1:6379> set name Jack ex 10
OK
127.0.0.1:6379> ttl name
(integer) 8
127.0.0.1:6379> get name
"Jack" # 此时是新增
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> keys *
1) "name2"
2) "k3"
3) "k2"
4) "k1"
5) "name3"
6) "score"
127.0.0.1:6379>
1.2 Hash类型
Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构(类似Map<key,Map<key,value>>但还是有差异的)。
String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便:
KEY | VALUE |
---|---|
heima:user:1 | {name:“Jack”, age:21} |
heima:user:2 | {name:“Rose”, age:18} |
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:
瑞:Hash结构相对String结构更加灵活,可以将value拆分为多个独立字段进行存储。
1.2.0 Hash类型的常见命令
- HSET key field value:添加或者修改hash类型key的field的值
- HGET key field:获取一个hash类型key的field的值
- HMSET:批量添加多个hash类型key的field的值
- HMGET:批量获取多个hash类型key的field的值
- HGETALL:获取一个hash类型的key中的所有的field和value
- HKEYS:获取一个hash类型的key中的所有的field
- HVALS:获取一个hash类型的key中的所有的value
- HINCRBY:让一个hash类型key的字段值自增并指定步长
- HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行
瑞:哈希结构是实际开发中常用的命令。Hash类型命令可以与String类型命令捆绑记忆,String类型命令前加上H就是Hash类型命令,语法上添加field指明是哪个字段即可
1.2.1 HSET 和 HGET
- HSET key field value:添加或者修改hash类型key的field的值
语法:
hset key field value [field value ...]
- HGET key field:获取一个hash类型key的field的值
语法:
hget key field
用法如下
127.0.0.1:6379> hset heima:user:3 name Lucy
(integer) 1
127.0.0.1:6379> hset heima:user:3 age 29
(integer) 1
127.0.0.1:6379> hget heima:user:3 name
"Lucy"
127.0.0.1:6379> hget heima:user:3 age
"29"
127.0.0.1:6379> hset heima:user:3 age 21
(integer) 0 # 返回0表示修改
127.0.0.1:6379> hget heima:user:3 age
"21"
127.0.0.1:6379>
使用客户端查看
1.2.2 HMSET 和 HMGET
- HMSET:批量添加多个hash类型key的field的值
语法:
hmset key field value [field value...]
- HMGET:批量获取多个hash类型key的field的值
语法:
hmget key field [field ...]
用法如下
127.0.0.1:6379> hmset heima:user:4 name HanMeiMei
OK
127.0.0.1:6379> hmset heima:user:4 name LiLei age 20 sex man
OK
127.0.0.1:6379> hmget heima:user:4 name age sex
1) "LiLei"
2) "20"
3) "man"
127.0.0.1:6379>
1.2.3 HGETALL
- HGETALL:获取一个hash类型的key中的所有的field和value
语法:
hgetall key
用法如下
127.0.0.1:6379> hgetall heima:user:4
1) "name"
2) "LiLei"
3) "age"
4) "20"
5) "sex"
6) "man"
1.2.4 HKEYS 和 HVALS
- HKEYS:获取一个hash类型的key中的所有的field
语法:
hkeys key
- HVALS:获取一个hash类型的key中的所有的value
语法:
hvals key
瑞:
HKEYS 可以理解成 Java 中 HashMap 的 keySet()
HVALS 可以理解成 Java 中 HashMap 的 entrySet()
用法如下
127.0.0.1:6379> hkeys heima:user:4
1) "name"
2) "age"
3) "sex"
127.0.0.1:6379> hvals heima:user:4
1) "LiLei"
2) "20"
3) "man"
1.2.5 HINCRBY
- HINCRBY:让一个hash类型key的字段值自增并指定步长
瑞:语法:
hincrby key field increment
,支持减操作
用法如下
127.0.0.1:6379> hincrby heima:user:4 age 2
(integer) 22
127.0.0.1:6379> hvals heima:user:4
1) "LiLei"
2) "22"
3) "man"
127.0.0.1:6379> hincrby heima:user:4 age 2
(integer) 24
127.0.0.1:6379>
127.0.0.1:6379> hincrby heima:user:4 age -10
(integer) 14
127.0.0.1:6379>
1.2.6 HSETNX
- HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行
语法:
hsetnx key field value
瑞:Hash类型的真正新增,和String类型不同,新增的是field-value
用法如下
127.0.0.1:6379> hsetnx heima:user:4 sex woman
(integer) 0
127.0.0.1:6379> hsetnx heima:user:3 sex woman
(integer) 1
127.0.0.1:6379> hgetall heima:user:3
1) "name"
2) "Lucy"
3) "age"
4) "21"
5) "sex"
6) "woman"
127.0.0.1:6379>
1.3 List类型
Redis 中的 List 类型与 Java 中的 LinkedList 类似,可以看做是一个双向链表结构(实际结构会更复杂)。既可以支持正向检索和也可以支持反向检索。
特征也与LinkedList类似:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。
1.3.0 List类型的常见命令
- LPUSH key element … :向列表左侧插入一个或多个元素
- LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
- RPUSH key element …:向列表右侧插入一个或多个元素
- RPOP key:移除并返回列表右侧的第一个元素
- LRANGE key star end:返回一段角标范围内的所有元素
- BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
瑞:将链表看作队列后:L可以理解为左侧,即队首。R可以理解为右侧,即队尾。
1.3.1 LPUSH 和 RPUSH
- LPUSH key element … :向列表左侧插入一个或多个元素
语法:
lpush key element [element ...]
用法如下
127.0.0.1:6379> lpush users 1 2 3
(integer) 3
注意:是 3 2 1,而不是按照命令顺序❌ 1 2 3 ❌
先左推1,此时:1
然后左推2,所以2在1的左边,此时:2 <-> 1
然后左推3,所以3在2的左边,此时:3 <-> 2 <-> 1
- RPUSH key element …:向列表右侧插入一个或多个元素
语法:
rpush key element [element ...]
用法如下
27.0.0.1:6379> rpush users 4 5 6
(integer) 6
右侧和正常逻辑相同,所以最终结果:3 <-> 2 <-> 1 <-> 4 <-> 5 <-> 6
1.3.2 LPOP 和 RPOP
- LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
语法:
lpop key [count]
- RPOP key:移除并返回列表右侧的第一个元素
语法:
rpop key [count]
瑞:如同出队类似,元素会从列表中移除
用法如下
# 开始3 <-> 2 <-> 1 <-> 4 <-> 5 <-> 6
# 移除并返回列表左侧的第一个元素3,此时2 <-> 1 <-> 4 <-> 5 <-> 6
127.0.0.1:6379> lpop users 1
1) "3"
# 移除并返回列表右侧的第一个元素6,此时2 <-> 1 <-> 4 <-> 5
127.0.0.1:6379> rpop users 1
1) "6"
1.3.3 LRANGE
- LRANGE key star end:返回一段角标范围内的所有元素
语法:
lrange key start stop
用法如下
# 开始3 <-> 2 <-> 1 <-> 4 <-> 5 <-> 6
# 移除并返回列表左侧的第一个元素3,此时2 <-> 1 <-> 4 <-> 5 <-> 6
127.0.0.1:6379> lpop users 1
1) "3"
# 移除并返回列表右侧的第一个元素6,此时2 <-> 1 <-> 4 <-> 5
127.0.0.1:6379> rpop users 1
1) "6"
127.0.0.1:6379> lrange users 1 2 # 返回下标为1的"1"到下标为2的"4"
1) "1"
2) "4"
1.3.4 BLPOP 和 BRPOP
- BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
语法:
blpop key [key ...] timeout
语法:brpop key [key ...] timeout
瑞:BLPOP、BRPOP跟LPOP、RPOP主要区别在于前者是阻塞式获取
用法如下
# 控制台1中
# 下面一条命令不符合blpop语法,因为等待时间必须指定
127.0.0.1:6379> blpop users2
(error) ERR wrong number of arguments for 'blpop' command
# 阻塞等待了近100秒后,仍然没有user2的数据,返回(nil)
127.0.0.1:6379> blpop users2 100
(nil)
(100.11s)
# 阻塞等待了近17.26秒后,使用控制台2对user2出入数据"Jack",此时返回列表
127.0.0.1:6379> blpop users2 100
1) "users2"
2) "Jack"
(17.26s)
127.0.0.1:6379>
# 新建控制台2,进入Redis命令行客户端,警告是指使用-a指令导致密码未加密,所以警告此操作不安全,学习时可直接忽略
[root@localhost ~]# redis-cli -h 127.0.0.1 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# 在控制台1执行blpop命令时插入数据
127.0.0.1:6379> lpush users2 Jack
(integer) 1
127.0.0.1:6379>
1.4 Set类型
Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
1.4.0 Set类型的常见命令
- SADD key member … :向set中添加一个或多个元素
- SREM key member … : 移除set中的指定元素
- SCARD key: 返回set中元素的个数
- SISMEMBER key member:判断一个元素是否存在于set中
- SMEMBERS:获取set中的所有元素
- SINTER key1 key2 … :求key1与key2的交集
- SDIFF key1 key2 … :求key1与key2的差集
- SUNION key1 key2 …:求key1和key2的并集
1.4.1 Set中对单个集合的操作命令
- SADD key member … :向set中添加一个或多个元素
语法:
sadd key member [member ...]
- SREM key member … : 移除set中的指定元素
语法:
srem key member [member ...]
- SCARD key: 返回set中元素的个数
语法:
scard key
- SISMEMBER key member:判断一个元素是否存在于set中
语法:
sismember key member
- SMEMBERS:获取set中的所有元素
语法:
smembers key
用法如下
# 向set-s1中添加元素a b c
127.0.0.1:6379> sadd s1 a b c
(integer) 3
# 获取set-s1中所有元素
127.0.0.1:6379> SMEMBERS s1
1) "c"
2) "a"
3) "b"
# 移除set-s1中的指定元素a
127.0.0.1:6379> srem s1 a
(integer) 1
# 判断a是否在set-s1中
127.0.0.1:6379> sismember s1 a
(integer) 0
# 判断b是否在set-s1中
127.0.0.1:6379> sismember s1 b
(integer) 1
# 返回set-s1中元素的个数
127.0.0.1:6379> scard s1
(integer) 2
127.0.0.1:6379>
1.4.2 Set中对多个集合的操作命令
- SINTER key1 key2 … :求key1与key2的交集
语法:
sinter key [key ...]
- SDIFF key1 key2 … :求key1与key2的差集
语法:
sdiff key [key ...]
- SUNION key1 key2 …:求key1和key2的并集
语法:
sunion key [key ...]
假设集合s1有元素A、B、C,集合s2有元素B、C、D
则s1和s2的交集、差集、并集如下
1.4.3 Set命令练习
将下列数据用Redis的Set集合来存储:
- 张三的好友有:李四.王五.赵六
SADD zs lisi wangwu zhaoliu
- 李四的好友有:王五.麻子.二狗
SADD ls wangwu mazi ergou
利用Set的命令实现下列功能:
- 计算张三的好友有几人
SCARD zs
- 计算张三和李四有哪些共同好友
SINTER zs ls
- 查询哪些人是张三的好友却不是李四的好友
SDIFF zs ls
- 查询张三和李四的好友总共有哪些人
SUNION zs ls
- 判断李四是否是张三的好友
SISMEMBER zs lisi
- 判断张三是否是李四的好友
SISMEMBER ls zhangsan
- 将李四从张三的好友列表中移除
SREM zs lisi
1.5 SortedSet类型
Redis 的 SortedSet 是一个可排序的 set 集合,与 Java 中的 TreeSet 有些类似,但底层数据结构却差别很大。SortedSet 中的每一个元素都带有一个 score 属性,可以基于 score 属性对元素排序,底层的实现是一个跳表(SkipList)加 hash 表。
SortedSet具备下列特性:
- 可排序
- 元素不重复
- 查询速度快
因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。
1.5.0 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
1.5.1 SortedSet命令练习
将班级的下列学生得分存入Redis的SortedSet中:
Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76
zadd stus 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry 92 Amy 76 Miles
并实现下列功能:
- 删除Tom同学
zrem stus Tom
- 获取Amy同学的分数
zscore stus Amy
- 获取Rose同学的排名
zrank stus Rose
- 查询80分以下有几个学生
zcount stus 0 80
- 给Amy同学加2分
zincrby stus 2 Amy
- 查出成绩后3名的同学
zrange stus 0 2
- 查出成绩前3名的同学
zrevrange stus 0 2
- 查出成绩80分以下的所有同学
zrangebyscore stus 0 80
如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~
相关文章:

瑞_Redis_Redis命令
文章目录 1 Redis命令Redis数据结构Redis 的 key 的层级结构1.0 Redis通用命令1.0.1 KEYS1.0.2 DEL1.0.3 EXISTS1.0.4 EXPIRE1.0.5 TTL 1.1 String类型1.1.0 String类型的常见命令1.1.1 SET 和 GET1.1.2 MSET 和 MGET1.1.3 INCR和INCRBY和DECY1.1.4 SETNX1.1.5 SETEX 1.2 Hash类…...
js 算法题 在数组中找出和为目标值 target 的那 两个 整数,并返回它们的数组下标
题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以…...
基于springboot接口的编写
目录 1、模糊分页查询 2、批量删除 3、新增 4、编辑 此接口非彼接口。此接口是MVC的设计模式中的Controller层,一般我们会叫Controller层里的方法为接口。他们是负责接收前端或者其它服务的传来的请求,并对请求进行相应的处理,最终再将处…...

【HarmonyOS】鸿蒙开发之Video组件——第3.7章
Video组件内VideoOptions属性简介 src:设置视频地址。currentProgressRate:设置视频播放倍速,参数说明如下: number|string:只支持 0.75 , 1.0 , 1.25 , 1.75 , 2.0 。P…...
React引入css的几种方式以及应用
1.直接引入css文件 import "./parent.css" 2.引入css模块,定义文件名[组件名.module.css];该方式可避免类名的重复,每个组件都有独立的作用域,避免了全局污染,保证了类名的唯一性 import styles from &qu…...

[算法沉淀记录] 排序算法 —— 冒泡排序
排序算法 —— 冒泡排序 基本概念 冒泡排序是一种简单的排序算法。它重复地遍历要排序的列表,一次比较两个元素,并交换它们的位置,如果它们不是按照升序排列的。这步遍历是重复进行的,直到没有再需要交换,也就是说该…...

【机器人最短路径规划问题(栅格地图)】基于遗传算法求解
基于遗传算法求解机器人最短路径规划问题(栅格地图)的仿真结果 仿真结果: 路径长度的变化曲线: 遗传算法优化后的机器人避障路径:...

如何做代币分析:以 TRX 币为例
作者:lesleyfootprint.network 编译:cicifootprint.network 数据源:TRX 代币仪表板 (仅包括以太坊数据) 在加密货币和数字资产领域,代币分析起着至关重要的作用。代币分析指的是深入研究与代币相关的数据…...
关于地址引用与值引用的坑
List<UserInfo> userInfoList new List<UserInfo>(); List<UserInfo> userInfoList_new new List<UserInfo>(userInfoList);userInfoList_new 与userInfoList 指的是相同的内存吗? 答: 在C#中,userInfoList_new …...

初谈软件工程(一)
我就读于兰州交通大学的软件工程专业。虽然在全国众多的985、211高校中,兰州交通大学可能并不显眼,似乎未能跻身这些所谓的“顶尖”行列就意味着不被认可。然而,在甘肃省的教育领域中,它无疑是一座璀璨的明珠,名列前茅…...
自动化开展思路
自动化开展思路 本人在公司一直从事自动化测试推进工作,最近在好友的邀请下去其就职的公司分享如何开展自动化测试! 希望能帮其解决如下几个痛点: 1.上线周期长; 2.测试时间紧张,上线信心不足,测试覆盖…...

安装使用zookeeper
先去官网下载zookeeper:Apache ZooKeeper 直接进入bin目录,使用powerShell打开。 输入: ./zkServer.cmd 命令,启动zookeeper。 zookeeper一般需要配合Dubbo一起使用,作为注册中心使用,可以参考另一篇博客…...

nginx实现http反向代理及负载均衡
目录 一、代理概述 1、代理概念 1.1 正向代理(Forward Proxy) 1.2 反向代理(Reverse Proxy) 1.3 正向代理与反向代理的区别 2、同构代理与异构代理 2.1 同构代理 2.2 异构代理 2.3 同构代理与异构代理的区别 二、四层代…...

vue组件中data为什么必须是一个函数
查看本专栏目录 关于作者 还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas&#x…...

科技论文编写思路
科技论文编写思路 1.基本框架2.课题可行性评估1.研究目标和意义2.研究方法和技术3.可行性和可操作性4.风险和不确定性5.经济性和资源投入6.成果预期和评估 3.写作思路4.利用AI读论文5.实验流程 1.基本框架 IntroductionRelated worksMethodExperiment and analysisDiscussionC…...

Windows虚拟机克隆后修改SID
在日常使用VMware Workstation我们经常会去克隆一些Windows操作系统的虚拟机,克隆的虚拟机和源虚拟机的系统安全标识符(Security Identifiers,SID)相同,SID是标识用户、组和计算机账户的唯一的号码。 如果两台虚拟机都…...
前端架构: 脚手架工具rxjs的快速上手应用
rxjs rxjs 是一个异步的库和Promise是非常的相似 文档:https://www.npmjs.com/package/rxjs Weekly Downloads 44,474,389 (动态数据) 说明这个库也是非常的流行 安装 $ npm i -S rxjs 使用 import { range, filter, map } from rxjs;range(1, 200).pipe(filte…...

小程序框架(概念、工作原理、发展及应用)
引言 移动应用的普及使得用户对于轻量级、即时可用的应用程序需求越来越迫切。在这个背景下,小程序应运而生,成为一种无需下载安装、即点即用的应用形式,为用户提供了更便捷的体验。小程序的快速发展离不开强大的开发支持,而小程…...

音视频数字化(数字与模拟-电影)
针对电视屏幕,电影被称为“大荧幕”,也是娱乐行业的顶尖产业。作为一项综合艺术,从被发明至今,近200年的发展史中,无人可以替代,并始终走在时代的前列。 电影回放的原理就是“视觉残留”,也就是快速移过眼前的画面,会在人的大脑中残留短暂的时间,随着画面不断地移过,…...
在 Ubuntu 中, 使用 fsck 命令来修复磁盘文件系统
在 Ubuntu 中,可以使用 fsck 命令来修复磁盘文件系统。fsck 是用于检查和修复文件系统的工具。 使用 fsck 命令修复磁盘文件系统的步骤如下: 首先,您需要在命令行终端窗口中以 root 用户身份登录。 使用 fdisk -l 命令列出所有磁盘设备。 …...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...