2 redis数据结构

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44655181/article/details/102678975

一 全局命令

针对的全是键的命令

1. keys * :
查看所有键, 遍历查询所有键获取,为避免影响性能,当线上环境有大量键时禁止使用该命令;
2. dbsize :
查看键的数量, dbsize是一个键数量的变量,读取该变量速度很快;
3. exists key:
键是否存在, 如果存在返回1,不存在返回0
4. del key [key…]:
删除键, 结果返回删除键的个数,可以删除多个键,例如:del key1,key2
5. expire key seconds:
设置键的过期时间,

使用ttl key命令来查看键的剩余过期时间,有3种结果:
1)>=0,表示剩余过期时间;
2)-1 键没设置过期时间;
3)-2 键不存在

6. type key:
键的数据结构类型

二 单线程架构

1 单线程模型

每条客户端命令传到redis服务端, 都不会立刻执行,先放到队列中存储, 然后被逐个执行。
每条命令的执行顺序是不确定的, 但是能保证不会同时执行两条命令,保证了并发的安全。
在这里插入图片描述

2 单线程为什么还那么快

a 纯内存访问:数据存储在内存中,读写速度快;
b 非阻塞I/O: redis使用I/O多路复用技术实现
c 单线程避免了多线程切换和竞态产生的消耗

在这里插入图片描述

三 数据结构

基于key-value键值对的数据结构,和mysql、mongodb的结构都不一样

1 5种数据结构

字符串(string) 哈希(hash) 列表(list) 集合(set) 有序集合(zset)
在这里插入图片描述

2 内部编码

1) object encoding key: 查看内部编码

#object encoding hello
> ziplist

2) 内部编码的意义:
当内部编码数据结构改变时,不会影响到对外的数据结构,扩展性好
在这里插入图片描述

3 应用场景

在这里插入图片描述
列表list和有序集合关于排行榜、有序列表场景的使用区别:
1 当数据量小的时候,两种数据结构都可以使用;
2 当数据量很大,列表list占用的空间笔有序集合小几倍,优先使用列表集合list

四 具体数据结构

4.1 字符串

1 值类型

字符串、数字(整数、浮点数)、二进制(图片、音频、视频)
在这里插入图片描述

2 命令

常用命令:

都是针对字符串的value操作的命令

(1)设置值

set key value: 设置key的值
setex key value seconds: 设置key值,并设置过期时间
setnx key value: key不存在才能设置成功,否则返回0
setxx key value: key必须存在才能设置成功

setnx的使用场景:
分布式锁(多条请求同时执行setnx 只有一个客户端能设置成功,其余都失败)

(2)获取值
get key: 获取key的值

如果key不存在,则返回nil(空)

(3)批量设置值
mset key value[key vaue …]

例如:

#mset a 1 b 2 c 3
>OK

(4)批量获取值
mget key[key…]

例如:

mget a b c
>1
>2
>3

mget提高了get效率:
n次get命令用时: n次网络连接 + n次命令执行时间
mget命令用时:1次网络连接 + n次命令执行时间
因redis每秒处理数万的读写操作,处理性能很高, 一般网络连接是性能的瓶颈,n次网络连接的用时特别长,性能较慢,所以获取很多值,可以用mget命令提高查询性能

(5)计数
incr key

执行结果返回3种:
a 不是整数,返回错误
b 整数,返回自增后的数据
c 键不存在,默认是0,返回自增后的1

不常用命令:

(1)字符串尾部追加值
append key value

例如:

get key
> hello
append key world
get key
>helloworld

(2)字符串长度
strlen key

(3)设置并返回原值
getset key value

例如:

get key
>hello
getset key world
> hello

(4)获取部分字符串

getrange key start end

例如:

get key
> dajiahao
getrange key 0 3
>daji

3 内部编码

1)有3种内部编码:

int 8个字节的长整型
embstr 小于等于39个字节的字符串
raw 大于39字节的字符串

2)redis根据类型和长度自动决定使用哪种内部数据结构

例如:

set key 1234
object encoding key
>int

4 使用场景

1)缓存
2)计数
3)session共享
在这里插入图片描述

4)限速

用户登录网站,1分钟验证码发送次数不能超过5次,就可以用redis进行存储次数

代码片段:

isExist = redis.set(key,1,"ex 60","nx");
if(isExist != null && redis.incr(key) <= 5){
//通过
.....
}else{
//不通过
......
}

4.2 哈希

1 数据结构

key-{{field1,value1},{field2,value2}} 值本身又是一个键值对

2 命令

都是针对的field-value进行的命令

1)设置值
hset key field value

eg:

hset user  name lisi
>1

2)获取值
hget key field

如果field不存在,会返回nil(空)

eg:

hget user name
>"lisi"

3)删除field
hdel key field[field …]

返回结果为成功删除field的个数

eg:

hdel user name
>1

4)field个数
hlen key

5)批量设置或批量获取field-value
hmset key field value[field value …]
hmget key field[field …]

6)判断field是否存在
hexists key field

7)获取所有的field
hkeys key

8)获取所有的value
hvals key

3 使用场景

1)缓存用户信息
类似于关系型数据表的结构,如下:
在这里插入图片描述

4.3 列表

1 简介:

1) 类似于java的LinkedList
2) 用来存储多个有序的字符串(元素只能是字符串类型
3)对列表两端插入和弹出元素使用push、pop命令

2 数据结构特点:

1)列表中元素是有序的, 因此可以通过下标获取、删除指定下标元素
2)列表中元素可以重复
在这里插入图片描述

在这里插入图片描述

3 命令

1)添加
rpush key value[value …] 从右侧添加元素
lpush key value[value …] 从左侧添加元素
linsert key before|after value1 value 从列表中找到值为value1的元素,在前面或后面插入元素value

2)查找
lindex key index 按指定下标查找元素
lrange key start end 从左侧开始查询下标为start-end的元素列表
llen key 获取列表的长度

查找都是从左侧开始的!!!

lrange索引下标有两个特点:
从左到右,下标为: 0~N-1
从右到左,下标为:-1~-N

3)删除
lpop key 从左侧删除一个元素
rpop key 从右侧删除一个元素
ltrim key start end 只保留下标为start-end之间的元素列表

lrem key count value  删除指定value元素
count的取值决定删除的value数量:
count > 0 ,从左到右,最多删除count个value元素
count < 0 ,从右到左,最多删除count绝对值个value元素
count=0, 删除所有值为value的元素

4)修改
lset key index newvalue 根据下标修改制定元素的值

5)阻塞
blpop
brpop
和lpop rpop类似,只是增加了阻塞操作

4 使用场景

1)消息队列
使用redis的lpush + brpop可以实现消息队列
在这里插入图片描述
2) 排行榜
list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名、斗鱼年终盛典主播排名等

3)文章列表
因列表是有序的,且可以根据索引进行搜索,用于文章列表是可行的,如下:
在这里插入图片描述

4.4 集合set

1 数据结构特点

1)无序
2)无重复数据
在这里插入图片描述

2 命令

2.1 集合内命令
1)添加元素
sadd key member[member …]

返回添加成功的个数

2)删除元素
srem key member[member …]

返回删除成功的个数

3)元素个数
scard key

scard是变量,读取性能快

4)判断元素是否在集合中
sismember key member

存在返回1,不存在返回0

5)随机从集合中返回指定个数集合
srandmember key [count]

count是可选的,不填默认值是1

6)从集合随机弹出(删除)一个元素
spop key

2.2 集合间命令
1)sinter key[key …] 集合间交集
2)sunion key[key …] 集合间并集
3)sdiff key[key …] 集合间差集
在这里插入图片描述

3 内部编码

1)intset(整数集合):
当集合内部元素是整数且元素个数小于512个,默认使用intset进行内部实现,减少内存开销

2)hashtable(哈希集合):
当不满足intset条件,或者元素不是整数也会使用hashtable进行内部实现

4 使用场景

标签tag. 不同的人有些对新闻感兴趣,有些对漫画感兴趣, 不同的兴趣就是标签, 根据标签可以获取对应的用户群体,根据标签推送给这部分符合标签的用户群体更多相关的消息, 从而提高用户体验。
在这里插入图片描述

4.5 有序集合

1. 数据结构特点

1)无重复数据,和集合set这点相似
2)有顺序,每个元素新增一个score作为排序的依据,集合中的元素不可以重复,但是score是可以重复的

在这里插入图片描述

2 命令

2.1 集合内命令
1)添加成员
zadd key score member[score member …]

2)计算成员个数
zcard key

3)计算某成员的分数
zscore key member

4)计算成员的排名
zrank key member

5)删除某成员
zrem key member[member …]

6)增加成员的分数
zincrby key increment member

eg:
zincrby key 50 member
给member原来的分数增加50

7)返回指定排名范围的成员
zrange key start end [withscores]
zrevrange key start end [withscores]
[withscores]可选,带上会显示分数

8)返回指定分数范围的成员
zrangebyscore key start end [withscores]
zrevrangebyscore key start end [withscores]

3 使用场景

score可以排名,典型的使用场景是排行榜

eg: 使用用户点赞数为维度,获取用户点赞的排行版情况
展示用户信息和分数、排名:
hgetall user:info:lisi
zscore user:ranking lisi
zrank user:ranking lisi

猜你喜欢

转载自blog.csdn.net/weixin_44655181/article/details/102678975