redis五种类型的经典使用场景


highlight: androidstudio

说明:
对于redis命令这里不在赘述 直接戳这里 redis命令手册 或者 这个也是命令手册 都可以

另外其原生命令和 RedisTemplate中的方法对应请戳这里 github 里边有具体的示例

String

这货是我们平时开发中用的比较多的,也是最简单的一种

1. 设置开关,标识 (配合nacos配置中心真的挺香的~~~)
2. 共享session如token 以及 incr操作
3. 将对象转为json串后(value为String)设置进redis
  • 但是这样做有个很明显的缺点就是如果你要修改对象的某一个字段,也得把整个对象的json串拿出来反序列化成对象,这样做得话有点不值得。

  • 那么我们如何优化一下呢?

    • 其实可以使用mset命令 如下

    • MSET key1 "Hello" key2 "World"

    image.png

    • 代码如下 image.png
    • but 这种的话,适用于字段较少 且存在频繁修改少量字段的情况下,否则没必要,直接转成json存进去就完事了。
4. 分布式锁
在之前的版本中 nx和ex不是原子的,后来才开始支持的。
  • set userId:101 lock ex 100 nx

image.png

在代码中我们可以这么做(只是演示哈,实际中推荐使用redisson 或者你自己造个轮子大家都认可的话也可以)

```java protected ValueOperations string;

//setnex Boolean nex = string.setIfPresent("setnex:key", "value",10,TimeUnit.SECONDS); System.out.println(nex); ```

当然关于分布式锁我也将会写一篇文章,我想的是仿照 Redisson 手写个,但是实际使用中我还是使用Redisson,因为其真的很强。 Redisson的github地址 其内部使用了netty,源码也相对简单是个很好的redis客户端。

List

基于List结构 我可以实现栈,队列,阻塞队列

    1. Stack(栈) = LPUSH + LPOP ,FILO先入后出 结合LPUSH和LPOP命令实现栈的先进后出的特性,LPUSH从左边入栈,LPOP从左边出栈,先进入 的 后出来。相当于入口出口是一个。
    1. Queue(队列)= LPUSH + RPOP,FIFO先进先出 结合LPUSH和RPOP命令实现队列的先进先出的特性,LPUSH从左边入队,RPOP从右边出队,先进来的先出来。相当于入口出口各在两边。
    1. Blocking Queue(阻塞队列)= LPUSH + BRPOP 结合LPUSH和BRPOP实现阻塞队列,BRPOP比RPOP多了一个timeout的参数,是一个等待的最大时间,如果在这个时间内拿不到数据则返回空。
    1. 还可以用它来做分页(如文章列表),以用户id为key 文章id+标题+文章(组装成对象)为value(当然肯定不是文章内容那样的话太占空间了,具体的文章内容需要点进去时候,才去加载),发表文章时候lpush,做查询时候 range(pageNum,pageSize)取出即可效率很高 (当然这么做需要根据实际情况去衡量是否合理)。
    1. 热点数据,在实际场景我们也这么用过,其实和第4点类似,只不过不存所有的数据,只往list放热点数据罢了。

Hash

使用hash用来存储对象也是比较合适的

其数据结构是和java中的hash一样的。但我记得有个区别是他的扩容(渐进式的 具体见黄建宏大佬的《redis设计与实现》书中有写)和java中的不一样。

下图中将对象存进hash结构中(注意: HK对应的值我在getObjectToMap方法中拼接了id以防止重复)

为什么我们叫它HK ? 源于下边代码(我觉得比较合适所以这里就称为HK了) ``` public interface HashOperations {

void putAll(H var1, Map extends HK, ? extends HV> var2);

} ```

image.png

我们发现使用String和hash都可以存对象,那什么时候用String什么时候用hash呢

适合用 String 存储的情况:

  • 每次需要访问大量的字段 (这时序列化的成本就没那么不值得了)
  • 存储的结构具有多层嵌套的时候 (hash对这种情况基本上很难处理)

适合用 Hash 存储的情况:

  • 在大多数情况中只需要访问少量字段 O(1)
关于hash 有个地方提一下
  • 过期功能不能使用在HK上,只能用在key上

另外电商中的购物车功能也可以用此结构

1.以用户id为key,商品id为(HK),商品数量为value(HV)可以实现购物车的常规操作

如下图:

image.png

Set

点赞

    1. 点赞 点赞就把点赞这个人的ID加到这个点赞的集合中 SADD like:{消息ID} {用户ID}
    1. 取消点赞 从集合中移除用户ID SREM like:{消息ID} {用户ID}
    1. 检查用户是否点过赞 SISMEMBER like:{消息ID} {用户ID}
  • 4.获取点赞的用户列表 SMEMBERS like:{消息ID}

    1. 获取点赞用户数

SCARD like:{消息ID}

当然像这种场景的话,还有更好的实现方式就是redis的BitMap,用他来记录这种true or false的场景简直不要太爽,当然这个的话必须要好好设计下key,以便在统计时候好操作。(顺便说一下他也有缺点的哦) 关于bitMap我后续也会写一篇文章来说明。

共同关注、可能认识的朋友,你关注的xxx是否也关注了yyy

image.png

看下图 可能认识的人 一般都有个来自什么什么

image.png

共同关注和我关注的xxx也关注了yyy这样的我在我手机中没找到,等哪天找到了在更新下吧。

ZSet

最经典的 微博的热搜排行榜

image.png

在有京东的热搜

image.png

。。。。各种热搜,或者什么排行榜等等;当需要以某某系数为权重进行排行的时候,就可以考虑使用ZSet了 ps:(其实ZSet对比set,就是多了一个按分值排序的功能)

除此之外什么点赞排行榜,评论排行榜等等也都可以考虑使用它;

  • 1 点击新闻

每次有人点击这个新闻,那么就给该条新闻的分值加1

ZINCRBY 热搜:20210826 1 A条新闻ID

  • 2 展示当日排行前十

取集合中的前10个元素

ZREVRANGE 热搜:20210826 0 10 WITHSCORES

  • 3 近四天热点榜单计算

``` 由于该命令不常用这里贴出语法 : ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

ZUNIONSTORE 近4天热搜计算2 4 热搜:20210823 热搜:20210824 热搜:20210825 热搜:20210826 AGGREGATE SUM ```

  • 4 展示近4日排行前十

ZREVRANGE 近4天热搜计算2 0 10 WITHSCORES

-----------------------------------华丽的分割线------------------------------------

下面我们把以上操作演示一下

image.png

现在我们为23,24,25 这几天也增加点数据后使用将这4天的sum起来并存储到新key(近4天热搜计算2)中其分组条件就是 key; 即以 (热搜:20210823 热搜:20210824 热搜:20210825 热搜:20210826 ) 这些作为分组条件 ZUNIONSTORE 近4天热搜计算2 4 热搜:20210823 热搜:20210824 热搜:20210825 热搜:20210826 AGGREGATE SUM

image.png

看下新key中的内容

image.png

展示近4日排行前十根据分值倒叙排序(他默认是正序的,想最大的在前那就肯定需要倒叙排序了)

image.png

ok就先到这里吧明天肝一篇缓存和bitmap的文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值