文章目录
Redis数据结构介绍
String类型
无论字符串是哪种格式,本质都是字符串,底层都是由字节数组
形式存储:
- 数值类型的字符串,把数字转为二进制形式进行存储,这样一个字节就可以存储更大的数字,更节省空间
- 普通字符串只能把字符转成对应的字节码进行存储,相对来说,占用的空间一般更大一些
1. String的常见命令
通过help @String
查看String类型的命令:
练习一下:
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> get age
"10"
# key的值为整型字符串, INCR让key的值自增1, INCRBY可以指定步长
127.0.0.1:6379> INCR age
(integer) 11
127.0.0.1:6379> INCRBY age 2
(integer) 13
127.0.0.1:6379> INCRBY age -1 # 自减1,步长设为-1, 也可以使用DECR
(integer) 12
127.0.0.1:6379> set k1 10.1
OK
127.0.0.1:6379> get k1
"10.1"
# key的值为浮点型字符串,INCRBYFLOAT 一定要指定步长
127.0.0.1:6379> INCRBYFLOAT k1 0.5
"10.6"
##### set命令可以添加很多选项 ###########
# 可以看到使用set命令,如果key已经存在,就会修改对应的value
127.0.0.1:6379> set name chenfei
OK
127.0.0.1:6379> set name laoyu
OK
127.0.0.1:6379> get name
"laoyu"
# 使用setnx命令,如果key存在,就不执行
127.0.0.1:6379> setnx k2 chenfei
(integer) 1
127.0.0.1:6379> setnx k2 laoyu
(integer) 0
127.0.0.1:6379> get k2
"chenfei"
# 当然set命令也可以添加nx选项,达到和setnx一样的作用
127.0.0.1:6379> set k2 laoyu nx
(nil)
127.0.0.1:6379> get k2
"chenfei"
# setex命令:添加键值对并且指定有效期 ---》 如果key值存在,就修改value值以及有效期
127.0.0.1:6379> setex k3 10 v3
OK
# set命令添加 ex 选项
127.0.0.1:6379> set k4 v3 ex 10 # 添加k3-v3键值对,设置有效期10s
OK
127.0.0.1:6379> ttl k4
(integer) 8
2. 思考
Redis的key允许有多个单词组成层级结构,多个单词之间用:
隔开,比如:
上图只是举例说明,格式并非固定。
例如,我们一个聊天服务器项目叫chat, 有user和friend两种不同类型的数据,可以这样定义key:
-
user相关的key:
chat:user:1
-
friend相关的key:
chat:friend:1
并且key以层级结构进行存储:
chat
- user
- 1
- friend
- 1
当然,不仅是String类型的key可以这样设置,其他类型也可以
3. 应用
- 对象存储
- 累加器
- 分布式锁
- 位运算
Hash类型
key的value是一个key-value的结构
1. Hash类型常用命令
(大部分命令都是key为String类型的命令前加一个H。。。)
通过help @HASH
查看String类型的命令:
练习一下:
# HSET key field value
127.0.0.1:6379> HSET chat:user:1 name chenfei
(integer) 1
# key类型为hash
127.0.0.1:6379> type chat:user:1
hash
# 获取key中某field的值
127.0.0.1:6379> HGET chat:user:1 name
"chenfei"
# 增加多个field值
127.0.0.1:6379> HMSET chat:user:2 name laoyu age 24 sex man
OK
# 获取key中所有的field的值
127.0.0.1:6379> HMGET chat:user:2 name age sex
1) "laoyu"
2) "24"
3) "man"
# 获取key中所有的field和value
127.0.0.1:6379> HGETALL chat:user:2
1) "name"
2) "laoyu"
3) "age"
4) "24"
5) "sex"
6) "man"
# 获取key中所有的field
127.0.0.1:6379> HKEYS chat:user:2
1) "name"
2) "age"
3) "sex"
# 获取key中所有field的值
127.0.0.1:6379> HVALS chat:user:2
1) "laoyu"
2) "24"
3) "man"
# 让key中某个field的值按照指定步长自增
127.0.0.1:6379> HINCRBY chat:user:2 age 2
(integer) 26
127.0.0.1:6379> HINCRBY chat:user:2 age 2
(integer) 28
127.0.0.1:6379> HINCRBY chat:user:2 age -2
(integer) 26
# 可以看到key中某个field已经存在的情况下,使用HSET会修改field的值
127.0.0.1:6379> HGET chat:user:1 name
"chenfei"
127.0.0.1:6379> HSET chat:user:1 name chengchen
(integer) 0
127.0.0.1:6379> HGET chat:user:1 name
"chengchen"
# HSETNX在key中某个field已经存在的情况下,不执行
127.0.0.1:6379> HSETNX chat:user:3 name glh
(integer) 1
127.0.0.1:6379> HGET chat:user:3 name
"glh"
127.0.0.1:6379> HSETNX chat:user:3 name qz
(integer) 0
127.0.0.1:6379> HGET chat:user:3 name
"glh"
3. 应用
- 对象存储
List类型
双向链表
1. List类型的常用命令
通过help @LIST
查看String类型的命令:
练习一下:
# 3 2 1
127.0.0.1:6379> LPUSH user 1 2 3
(integer) 3
# 3 2 1 4 5 6
127.0.0.1:6379> RPUSH user 4 5 6
(integer) 6
# LRANGE key start end [start, end] 左右闭合
127.0.0.1:6379> LRANGE user 0 5
1) "3"
2) "2"
3) "1"
4) "4"
5) "5"
6) "6"
# LPOP|RPOP key [count] count表示要弹出的个数,不设置的话默认为1
127.0.0.1:6379> LPOP user
"3"
127.0.0.1:6379> RPOP user
"6"
127.0.0.1:6379> LPOP user 2
1) "2"
2) "1"
当列表中没有元素时,通过BLPOP|BRPOP
弹出元素时,会发生阻塞,阻塞时间由用户设置,在这段时间内,有新的元素插入列表时,唤醒BLPOP|RBPOP,并弹出元素:
BLPOP|BRPOP key [key ...] timeout
0表示永久阻塞
2. 思考
3. 应用
-
栈
-
队列
-
阻塞队列 ----- 关键特性
- 分布式公平锁
-
异步消息队列
-
获取固定窗口记录(战绩)— 显示最近的n条记录
- 使用List类型可以确保插入有序
- 每次获取固定区间内的记录
Set类型
HashMap中value为null
1. Set类型的常用命令
通过help @SET
查看String类型的命令:
练习一下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifq1BQV4-1666801827458)(C:\Users\chenfei\AppData\Roaming\Typora\typora-user-images\image-20221026195111502.png)]
# user:zs 和 user:lisi就表示张三和李四的好友列表
127.0.0.1:6379> SADD user:zs lisi wangwu zhaoliu
(integer) 3
127.0.0.1:6379> SADD user:lisi wangwu mazi ergou
(integer) 3
# 统计集合元素个数
127.0.0.1:6379> SCARD user:zs
(integer) 3
# 求交集,统计共同好友
127.0.0.1:6379> SINTER user:zs user:lisi
1) "wangwu"
# 求张三和李四的差集
127.0.0.1:6379> SDIFF user:zs user:lisi
1) "lisi"
2) "zhaoliu"
# 求并集
127.0.0.1:6379> SUNION user:zs user:lisi
1) "zhaoliu"
2) "wangwu"
3) "lisi"
4) "ergou"
5) "mazi"
127.0.0.1:6379> SISMEMBER user:zs lisi
(integer) 1
127.0.0.1:6379> SISMEMBER user:lisi zhangsan
(integer) 0
# 将李四从张三好友列表中移除
127.0.0.1:6379> SREM user:zs lisi
(integer) 1
# 查看集合所有元素(张三的所有好友)
127.0.0.1:6379> SMEMBERS user:zs
1) "zhaoliu"
2) "wangwu"
3. 应用
- 抽奖池
- 共同关注
- 推荐好友
SortedSet(ZSET)类型
1. SortedSet类型的常用命令
练习一下:
127.0.0.1:6379> ZADD stus 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry 92 Amy 76 Miles
(integer) 6
127.0.0.1:6379> ZREM stus Tom
(integer) 1
127.0.0.1:6379> ZSCORE stus Amy
"92"
# 因为默认是按照score升序排序,所以获取正向的排名应该逆序
127.0.0.1:6379> ZREVRANK stus Rose
(integer) 3
127.0.0.1:6379> ZCOUNT stus 0 80
(integer) 2
127.0.0.1:6379> ZINCRBY stus 2 Amy
"94"
# 排名从1开始
127.0.0.1:6379> ZREVRANGE stus 1 3
1) "Lucy"
2) "Jack"
3) "Rose"
127.0.0.1:6379> ZRANGEBYSCORE stus 0 80
1) "Miles"
2) "Jerry"
3. 应用
- 百度热榜(排行榜)
- 延时队列
- 分布式定时器
- 时间窗口限流