redis使用场景(8种类型)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

今天来介绍一下,redis的各个数据结构以及他们的使用场景。本人水平有限,如有误导,欢迎斧正,一起学习,共同进步!


一、redis的8种数据类型?

redis中一共有8种数据类型,有5种基本数据类型和3种特殊数据类型
基本数据类型:String、List(集合)、Set(集合)、ZSet(有序集合)、Hash(哈希)
特殊数据类型:geospatial(地理位置)、hyperloglog(优点:占用内存小)、Bitmap(位图)

1、string类型

string类型中,可以存储字符串、数字、二进制(bit)。常用命令如下:

set  key  value   ex  10  nx     是setnx  key  value;expire  key  10  的整合。代表10秒过期。
incr key		自动对key的value  进行加1的操作,value必须是数字类型
decr key
incrby  key  num    自动对key的value进行,value+num 在赋值给value的操作,
decrby  key  num

2、hash类型

string于hash是最常用的,hash的结构是 key-filed-value 这种格式的。常用命令如下:

hset			存入一个  key  filed  value    的散列结构
hsetnx		存入一个  key  field  value  ,若key已经存在,则操作失败,不存在,成功
hget			获取指定的key
hmset		批量存入  key  field
hmget		批量获取  key  field
hdel 		删除指定的  key  field
hincrby		对key  field的数值,进行加减操作

3、list类型

常用命令如下:

lpush  key  value  [value ...]	往key的列表键中左边放入一个元素,key不存在则新建
rpush  key  value  [value ...]	往key的列表键中右边放入一个元素,key不存在则新建
lpop  key  				从key的列表键最左端弹出一个元素
rpop  key					从key的列表键最右端弹出一个元素(从列表中删除)
lrange  key  start   stop		获取列表键从 start 下标到  stop  下标的元素    lrange key 0 -1 全部
blpop  key[key...]  timeout	阻塞的从key的列表键最左端弹出一个元素,若列表键中不存在元素,	
阻塞的等待{timeout}秒,若{timeout}=0,一直阻塞
brpop   key[key...]  timeout	阻塞的从key的列表键最右端弹出一个元素,若列表键中不存在元素,
阻塞的等待{timeout}秒,若{timeout}=0,一直阻塞

4、set类型

常用命令如下:

sadd  key  member [member...]		往集合键key中存放元素,做key不存在,则新增
srem  key  member [member...]		从集合键key中删除元素		(srem  sremove 删除的意思)
smembers  key					获取集合键key中所有元素
scard  key						获取集合键key的元素个数
sismember  key  member			判断member元素是否存在于集合键key中
srandmember  key  [count]			从集合键key中选出{count}元素,不从集合键中删除
spop  key  [count]					从集合键key中选出{count}元素,并且从集合键中删除
count是个数,代表从key中删除这么多个元素(随机删)。redis3.2以后的版本支持该命令
SET 的话,还能:
交集运算:
sinter   key   [key...]
sinterstore  destination   key  [key...]
并集运算:
sunion  key  [key...]
sunionstore  destination  key [key...]
差集运算:
sdiff  key   [key...]
sdiffstore   destination  key  [key...]

假设 有三个set
 set1  a、b、c
 set2  b、c、d
 set3  c、d、e
 
 则
 sinter  set1  set2  set3		c
 sinterstore  destination  set1   set2  set3   : 将set1、23的并集set进key值叫 destination 里面
 sunioin  set1  set2  set3		a、b、c、d、e
 sdiff set3  set2  set1			e	(这个是有参照物的,set3 和 set2 相比的话,有e是set2中没有的。在跟set1相比,set1也没有e,所以是e)

5、zset类型的命令

zadd  key  score  element  [...]		往有序集合键key中存放元素,score是分值,element是元素。若key不存在,则新建
zrem  key  element  [...]				往有序集合键key中删除元素
zscore	key  element					获取有序集合键key中element元素的score值
zincrby  key  increment  element		给有序集合key中的element元素进行score值操作,
										increment的值可以是正数,可以是负数。若key不存在则新建,element元素不存在则新增后进行score操作
										zcard  key								获取有序集合key中的元素个数
zrange  key  start  stop  [withscores]	正序获取有序集合key从start下标到stop下标的元素。
加上后面的 withscores 则会将对应的分值也打印,不加的话,只会打印出开元素
zrevrange  key  start  stop  [withscores]	倒序获取有序集合key从start下标到stop下标的元素
集合运算操作
zunionstore	 destkey  numkeys  key [key..]	并集计算	(非常常用)
zinterstore	 destkey  numkeys  key [key..]	交集计算 (并不常用)

6、geospatial & hyperloglog & Bitmap

顾名思义。geospatial 是地理位置,hyperloglog是log,Bitmap 是位图。其中 hyperloglog 的一大特点是占用内存小。

二、使用场景

1、string类型

  • 数据缓存,加快响应时间,提高用户体验。
  • 分布式锁(这个可以参照下面的“string比hash的优点 3 ”)

string与hash几乎是最常用的,这里就不多做介绍了

2、hash类型

  • 购物车功能
    添加 hincrby {userId} : shoppingCart {goodsId} {count}
    查询 hget {userId} : shoppingCart
    意思是说,每个用户都有自己的购物车(所以把购物车当做key),购物车里面的每个商品,当做 hash结构的field; 每个商品的数量,当做 hash结构的value。要是用户对同一个商品,件数选的2的话,就将value加1即可。因为是用户id和商品id,所以像商品单价,商品名称之类的,都可以拿到。
  • 菜单数据的缓存
    比如说,你的菜单有,ics-km系统和ics-customer系统,每个系统下面都有各自的类型,各自类型的值。比如说ics-km系统的渠道有官网、支付宝、微信、拼多多、小程序等。你就可以用hash结构 key-field-value 结构中,key是ics-km,field是支付宝,value是0。代码如下(示例):
hset ics-km-channel Alipay 0 Wechat 1 

3、list类型

  • 可以实现消息的队列。因为他有一个命令叫做 blpop key timeout。阻塞的等待timeout秒。可以用provider往队列中插入消息,consumer阻塞的从队列中消费消息,虽然不像专门的消息队列那样,有顺序性、持久性的解决方案,但是也能实现这个功能(需要从别的地方限制)

  • 可以实现,关注的列表的最新的消息。比如说,你关注的人有张三、李四,俩人。那你 2021.8.3 看的时候,应该是推送的 2021.8.3 的内容;你 2021.8.4 看的时候,应该推送的就是 2021.8.4 的消息了。那么怎么实现,最新的消息,放在最前面呢?可以用redis的 rpush key v 来实现,往最前面推送最新的消息。

4、set类型

  • 比如说是抽奖。微博有博主说,你转发我的微博,我随机抽奖。(或者是刷礼物抽奖什么的),比如说,谁转发了你的微博,你就 sadd key userid,将这个用户id添加到这个key里面。然后第二个人转发了,在把第二个人的用户id添加到这个key里面。最后,该抽奖的时候,看你的规则了,如果是一个人只能中一个奖,你就 spop key 2 。(此处假设二等奖有2人,就随机抽2人中奖,并且中奖后就从这个key中移出来了)。若是可以重复中间,你可以 srandmember key 3 ,随机抽3人中奖,并且中奖后,中奖人员仍在key里面,仍可以参与下次抽奖。
  • 可以做点赞、签到、我收藏的知识…等等
比如说用户1001点赞了 标识是8001的帖子,可以:	SADD  like_8001  1001
用户又取消了点赞:			SREM	like_8001   1001
检查用户1001是否点赞过		SISMEMBER   like_8001  1001
获取帖子8001的点赞过的用户		SMEMBERS	like_8001
获取帖子8001的点赞用户总数		SCARD	like_8001
  • 可以用作 用户推荐、商品推荐等等(比如说抖音的 可能关注的人)
张三(关注的人有):	zhangSub	--> 	{li,wang,zhao}
李四:	liSub				--> 	{zhang,wang,zhao,tian}
王五:	wangSub				--> 	{zhang,li,zhao,tian}
张三打开李四的主页
张三和李四的共同关注:				SINTER	zhangSub  liSub	 -->	{wang,zhao}
张三关注的人中也关注着他(互相关注)	SISMEMBER	wangSub	li、SISMEMBER  zhaoSub  li、..      (把张三的关注人全部遍历一遍,看看关注人的关注列表中有没有张三)
张三可能认识的人					SDIFF	liSub  zhangSub	-->		{zhang,li}	// 因为张三进李四的主页,给张三推荐可能认识的人,就把李四的关注有的,张三的关注没有的,推荐给张三

5、zset类型

  • 单日排行榜(新闻的热榜啊,知识的热榜啊什么的)。比如说,你新建一个zset的key:
    zadd hostNewId_date 1 newId // 新建一个 热点新闻id_日期 1 新闻id 的key
    zincrby hostNewId_date 1 newId // 每次被点击时加1
    zrevrange hostNewId_date 0 15 withscores // 拿到热榜的前15个,并展示数值。
  • 周榜、月榜、年榜等排行榜。比如说,你是用的 知识Id_日期 当做redis的zset的key,那么统计周榜的时候,就是用 zunionstore 合并后的key名 7 key1…key
    7 (zunionstore是固定的,合并后的key是随便起的,7是key的个数,后面是每个key的值) 统计出来7天的key,然后用 zrevrange key 0 10 拿到前10条数据。同样的能拿到月榜、年榜。

三、其他

1、hash 比 string 的优点?

1、可以将信息凝聚在一起,便于管理
2、从一定程度上可以避免误操作,减少key冲突
3、减少内存/io/cpu 的消耗(这点是说,redis是针对于key的扫描,检索,ttl过期之类的都是针对于这个key的,虽然这个key里面有多个field,但是还是只有一个key。若是使用字符串的话,要想达成同样的目的,则会产生大量的key,会产生大量的key的一个扫描,而使用一个key的话,会减少最外层的key的,cpu的消耗。比如说key是冲突啊,对key的管理啊什么的,一个key所消耗的资源肯定比多个key所消耗的资源少)

2、string 比 hash 的优点?

1、hash的field,是没有过期的功能的。他只能设置key的过期时间,不能给单独的某个field设置过期时间(所以redis的hash是不能用做分布式锁的,只能是string来当分布式锁)
2、hash 结构,是不支持 二进制的一些命令的,而string类型则支持(setbit、getbit、bitcount…)
3、在redis集群中,要想将数据分布,不能用 hash 。在redis3.0的custer集群中, 是对key值做hash,然后取模,(是采用hash巢,基于key的crc16哈希函数的计算,然后跟哈洗巢进行取模,哈洗巢基于不同的硬件进行一个管理,)拿到一个位置的,当key一样的时候,位置一定是一样的,也就是说,一定是一个物理机上的,不能分布的存储。因为string类型的话,key是不同的,而hash类型的话,key是相同的,key中的field是不同的,但是集群的时候,是根据key来进行运算的,而不是根据field

总结

这里只是简单的介绍了一下redis的使用场景,以后会跟大家分享一下redis的底层原理与具体实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值