Redis5种数据结构讲解及使用场景

                            Redis5种数据结构讲解及使用场景

redis存储:
1,redis可以作为内存数据库,也可以把数据持久化到磁盘上;大部分情况下,都是把redis作为内存数据库;
2,默认情况下
#after 900 sec (15 min) if at least 1 key changed
#after 300 sec (5 min) if at least 10 keys changed
#after 60 sec if at least 10000 keys changed
在redis配置文件中:
save 900 1
save 300 10
save 60 10000
3,数据默认存储在安装目录下.rdb文件中(可以在配置文件中dbfilename dump.rdb配置);
4,redis也可以设置为append模式,每次key的修改都会append到文件中,这种方式有可能丢失60秒的数据;
通过配置:appendonly yes开启
  appendfilename "appendonly.aof"设置append文件;
可以设置append的模式(类似于mysql的事务文件同步机制):
     # appendfsync always:每次更新key及时同步到append文件;
     # appendfsync everysec:每一秒同步一次key的更新;
    # appendfsync no:不管理append文件的更新,根据操作系统去定


一、字符串 String
String 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字。

字符串类型是redis最基础的数据结构,首先键是字符串类型,而且其他几种结构都是在字符串类型基础上构建的,所以字符串类型能为其他四种数据结构的学习尊定基础。字符串类型实际上可以是字符串(简单的字符串、复杂的字符串(xml、json)、数字(整数、浮点数)、二进制(图片、音频、视频)),但最大不能超过512M。

常用命令:get、set、incr、decr、mget等。

添加/修改数据
set key value
获取数据
get key
删除数据
del key
添加/修改多个数据
mset key1 valueq key2 value2 …
获取多个数据
mget key1 key2 
获取数据字符个数(字符串长度)
strlen key
追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
append key value
incr key             //自增1
incrby key increment  //增加指定数值
incrbyfloat key increment  //增加一个浮点数
decr key             //自减1
decrby key increment //减少指定数值

string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。string类型是Redis最基本的数据类型,一个键最大能存储512MB。


二、哈希 Hash

在redis中哈希类型是指键本身又是一种键值对结构,如 value={{field1,value1},......fieldN,valueN}}
常用命令:hget,hset,hgetall 等。

添加/修改数据
hset key field value
获取数据
hget key field
hgetall key
删除数据
hdel key field1 [field2]
添加/修改多个数据
hmset key field1 value1 field2 calue2
获取多个数据
hmget key field1 field2 …
获取哈希表中字段的数量
hlen key
获取哈希表中是否存在指定的字段
hexists key field
获取哈希表中所有的字段名和字段值
hkeys key //字段名
hvals key //字段值
设置指定字段的数值数据增加指定范围的值
hincrby key field increment //指定数值增长指定的数
hincrbyfloat key field increment
创建数据,如果有则不再创建,如果没有则创建
hsetnx key field value


应用场景:我们简单举个实例来描述下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:
用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,主要有以下2种存储方式:
第一种方式:将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题
第二种方法:是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的
使用场景:存储部分变更数据,如用户信息等。
Hash是一个健值对集合,是一个String类型的key与value的映射表,特别适合用于存储对象。
使用场景:存储、读取、修改用户属性

三、列表List

列表类型是用来储存多个有序的字符串,列表中的每个字符串成为元素(element),一个列表最多可以储存2的32次方-1个元素,在redis中,可以队列表两端插入(pubsh)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下表的元素等,列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发中有很多应用场景。

常用命令:lpush,rpush,lpop,rpop,lrange等。
添加/修改数据
lpush key value1 [value2] …
rpush key value1 [value2] …
获取数据
lrange key start stop //获取从左数第start到stop个元素,从0开始
lindex key index //查询第i个元素
llen key //list的长度
获取并移除数据
lpop key //获取并删除左边第一个元素
rpop key //获取并删除右边第一个元素
list 类型数组扩展操作
规定时间内获取并移除数据
blpop key1 [key2] timeout
brpop key1 [key2] timeout
移除指定数据
lrem key count value //count为移除的数量,value为移除哪个值

list可用于秒杀抢购场景
在商品秒杀场景最怕的就是商品超卖,为了解决超卖问题,我们经常会将库存商品缓存到类似MQ的队列中,多线程的购买请求都是从队列中取,取完了就卖完了,但是用MQ处理的化有点重,这里就可以使用redis的list数据类型来实现,在秒杀前将本场秒杀的商品放到list中,因为list的pop操作是原子性的,所以即使有多个用户同时请求,也是依次pop,list空了pop抛出异常就代表商品卖完了。
基本操作:
//库存为3瓶可乐
> rpush goods:cola cola cola cola
(integer) 3
> lpop goods:cola
"cola"
> lpop goods:cola
"cola"

四、集合 set

集合类型也是用来保存多个字符串的元素,但和列表不同的是集合中不允许有重复的元素,并且集合中的元素是无序的,不能通过索引下标获取元素,redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,并合理的使用好集合类型,能在实际开发中解决很多实际问题。


添加数据
sadd key menber1 [member2]
获取全部数据
smembers key
删除数据
srem key member1 [member2]
获取集合数据总量
scard key
判断集合中是否包含指定数据
sismember key member
随机获取集合中指定数量的数据
srandmember key [count]
随机获取集合中的某个数据并将该数据移出集合
spop key
求两个集合的交、并、差集
sinter key1 [key2] //交集
sunion key1 [key2] //并集
sdiff key1 [key2] //差集(key1有但是key2没有的)

求两个集合的交、并、差集并存储到指定集合中
sinterstore destination key1 [key2]
sunionstore destination key1 [key2]
sdiffstore destination key1 [key2]

将指定数据从原始集合移动到目标集合中
smove source destination member

redis的set相当于java中的HashSet,内部的健值是无序唯一的,相当于一个hashmap,但是value都是null。set数据类型其实没什么好讲的,使用场景也是比较单一的,就是用在一些去重的场景里,例如每个用户只能参与一次活动、一个用户只能中奖一次等等去重场景
基本操作
127.0.0.1:6379> sadd userset 10001
(integer) 1
127.0.0.1:6379> sadd userset 10002
(integer) 1
127.0.0.1:6379> sadd userset 10001
(integer) 0
127.0.0.1:6379> sadd userset 10003 10004
(integer) 2
127.0.0.1:6379> smembers userset
1) "10001"
2) "10002"
3) "10003"
4) "10004"

五、有序集合 sorted_set

有序集合和集合有着必然的联系,他保留了集合不能有重复成员的特性,但不同得是,有序集合中的元素是可以排序的,但是它和列表的使用索引下标作为排序依据不同的是,它给每个元素设置一个分数,作为排序的依据。(有序集合中的元素不可以重复,但是csore可以重复,就和一个班里的同学学号不能重复,但考试成绩可以相同)


sorted_set类型数据的基本操作
添加数据
zadd key score1 member1 [score2 member2]
获取全部数据
zrange key start stop [WITHSCORES]//按照从小到大的顺序,加上WITHSCORES,就会带上scores一起显示
zrevrange key start stop [WITHSCORES]//按照从大到小的顺序
删除数据
zrem key member [member …]
按条件获取数据
//查询scores在某个范围内的值
zrangebyscore key min max [WITHSCORES] [LIMIT]
//查询key某个索引范围内的值
zrevrangebyscore key max min [WITHSCORES]
条件删除
zremrangebyrank key start stop
zremrangebyscore key min max
min与max用于限定搜索查询的条件
start与stop用于限定查询范围,作用于索引,表示开始和结束索引
offset与count用于限定查询范围,作用于查询结果,表示开始位置和数据总量
获取集合数据总量
zcard key //获取总量
zcount key min max //获取某一个范围的总量
集合交、并存储操作
zinterstore destination numkeys key [key …] //求和
zunionstore destination numkeys key [key …]
获取数据对应的索引(排名)
zrank key member //正数第几位
zrevrank key member //倒数第几位
score 值获取与修改
zscore key member //获取
zincrby key increment member //score递增 increment

各类热门排序场景
例如热门歌曲榜单列表,value值是歌曲ID,score是播放次数,这样就可以对歌曲列表按播放次数进行排序。
当然还有类似微博粉丝列表、评论列表等等,可以将value定义为用户ID、评论ID,score定义为关注时间、评论点赞次数等等。
基本操作:
这里的例子就是对用户的评分进行排序。
127.0.0.1:6379> zadd userzset 100 10002
(integer) 1
127.0.0.1:6379> zadd userzset 98 10001
(integer) 1
127.0.0.1:6379> zrange userzset 0 100
1) "10001"
2) "10002"

参考网址
https://blog.csdn.net/zzu_seu/article/details/106323114
https://zhuanlan.zhihu.com/p/161311820
https://www.cnblogs.com/agilestyle/p/11532375.html
https://blog.csdn.net/m0_38068812/article/details/89763846
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值