Redis学习(一)—生活中实用场景帮助理解redis的五种基本数据类型


Redis面试常问,由于我在实际开发中很少用,所以虽然看了很多次,但都不够深刻,不能举一反三。为了深入理解,这里总结它的常用场景,深刻理解Redis

有需要的同学务必照着例子敲一遍,多思考、多回顾,才能在实际使用中如鱼得水

(一)String

(1)业务场景1——分库分表后获取唯一id
 incr key  //自增1
 incrby key increment //增加指定数值
 incrbyfloat key increment //增加一个浮点数

注意

  1. string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算
  2. redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响
  3. 按数值进行操作的数据,如果原始数据不能转成数值,或超过了redis数值上线范围,将会报错。9223372036854775807 (java中long型数据最大值,Long.MAX_VALUE)
(2)业务场景2——数据时效性设置

场景:

  1. 某某综艺”,启动海选投票,只能通过微信投票,每个微信号每4个小时只能投1票。
  2. 电商商家开启热门商品推荐,热门商品不能一直处于热门期,每种商品热门期维持3天,3天后自动取消热门
  3. 新闻网站会出现热点新闻,热点新闻最大的特征是对时效性,如何自动控制热点新闻的时效性

【解决思路】

设置数据具有指定的生命周期。redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作。说白了,就是设置键的过期时间,业务层判断一个商品过期了,就不能放在热门商品推荐

  1. 增加/修改键值对并为其指定过期时间:setex key seconds value
  2. 功能与上面一样,秒的单位不同:psetex key milliseconds value
(3)业务场景3——高频数据访问显示

场景:主页高频访问信息显示控制,例如微博大V主页显示粉丝数与微博数量,这些数据就是热度数据,不断发生变化(一直有用户访问、数据在不断变化),这些数据如何放入Redis?

实现方式一

为大V用户设定用户信息,以用户主键和属性值作为key,后台设定时间定时刷新即可。

> set user:340823:blogs 100  //设置微博数量100
> set user:340823:fans 100000  //粉丝数100000
> set user:340823:focus 400  //关注数:400

在redis中的存储结构如下

实现方式二

以json格式存储大V用户,定时刷新,在代码中将对象转换为Json存储


(二)Hash

对某个门类,再进行细分

场景

  1. 比如说用户购物车,细分到用户有多个商品,每个商品有不同的属性;
  2. 商品优惠券,有不同的券额,30,50,100等等…获取的数量也不一样
  1. 库中已存在user的name为zhangsan的数据,再设置(hset)user的name为lisi,可以设置成功
    > hset user name lisi
    (integer) 0
    >hget user name
    "lisi"
    
  2. 使用hsetnx修改user的name为wangwu
    >hsetnx user name wangwu
    (integer) 0
    >hget user name
    "lisi"
    

hsethsetnx命令,前者是覆盖之前的设置,后者是如果不存在才设置成功,存在就设置不成功

(1)业务场景1——购物车的实现

【基本操作】

  • 以客户id(user1)作为key,每位客户创建一个hash存储结构存储对应的购物车信息

  • 添加商品:追加全新的field和value

  • 浏览,遍历hash

    获取全部的属性名和属性值(获取商品及对应的数量):hgetall user1
    获取字段名(获取商品list):hkeys user1
    获取字段值:hvals user1

  • 更改数量:自增/自减,设置value的值

    hincrby user1 food01 3

  • 删除商品:删除field

    hdel user1 food01

  • 清空购物车,删除key

阶段一:仅存储商品数量

在Redis中存储的结构


当前仅仅是将数据存储到Redis中,并没有起到加速的作用,因为我们仅仅查询到了用户商品id和数量,商品详细信息还需要二次查询数据库;

阶段二:存储商品数量及其他信息(图片等等)

优化:购物车中的商品记录保存成两条field

field1:专用于保存购买数量

【g001:nums 2】

  • 命名格式:商品id:nums
  • 保存数据:数值(2)

field2 :专用于保存购物车中显示的信息,包含文字描述、图片地址、所属商家信息等等
【g001:info {images}】

  • 命名格式:商品id:info (g001:info)
  • 保存数据:json ({images})

在Redis中的存储结构

但是出现很多用户都将同一个商品加入购物车,就会出现大量的重复信息,例如商品信息重复

阶段三:商品信息保存为哈希
> hset g001 info {images}
(2)业务场景2——抢购活动,限购发放优惠券、激活码等

【解决方案】

  • 以商家id作为key(比如电信)
  • 将参与抢购的商品id作为field(30元的券、50元)
  • 将参与抢购的商品数量作为对应的value(各含1000张)
  • 抢购时使用降至的方式控制产品数量

(三)List(有序的)

使用场景

  • 朋友圈点赞
  • 微信消息提醒,最近的消息在最上面
  • 微博个人关注列表,最近关注的在最上面

【基本操作】

lpush key value1[value2]...
rpush key value[value2]...

查看所有key:lrange key 0 -1
获取并删除左边第一个元素:lpop key
获取并删除右边第一个元素:rpop key

(1)业务场景1——朋友圈点赞

功能:按照点赞顺序显示点赞好友信息,如果取消点赞,移除对应好友信息

【解决方案】

  • rpush添加数据,先进先出
  • 移除指定数据(类似某个人取消点赞)
(2)业务场景2——最新消息的展示,最近关注,粉丝列表等

使用场景

  1. 微博中关注列表需要按照用户的关注顺序进行展示,最新关注在最上面;粉丝列表同理
  2. 新闻、资讯类网站将最新的新闻或咨询按照发生的事件顺序展示
  3. 企业运营过程中,系统将产生大量的运营数据,如何保障堕胎服务器操作日志的统一顺序输出

【解决方案】

  • 依赖list的数据具有顺序的特征对信息进行管理
  • 使用队列模型解决多路信息汇总合并的问题
  • 使用栈模型解决最新消息的问题

(四)Set(无序的,不能重复的)

使用场景

  • 随机推荐类索引
  • 每位员工有多个角色,角色权限的合并;
  • 同类型不同数据的合并操作:两个用户的共同好友之类
  • 访问量的统计

【基本操作】

  1. 添加数据:sadd key member1[member2]
  2. 获取全部数据:smembers keys
  3. 删除数据:srem key member1[member2]
  4. 获取集合数据总量:scard key
  5. 判断集合中是否包含指定数据:sismember key member
  6. 随机获取集合中指定数量的数据:srandmember key [count]
  7. 随机获取集合中的某个数据并将该数据移出集合:spop key
(1)业务场景1——随机操作数据

【场景分析】

  • 每位用户首次使用进入头条的时候会设置3项爱好的内容,但后期为了增加用户的活跃度、兴趣点、必须让用户对其他信息类别逐渐产生兴趣,增加用户留存度,如何实现?

【业务分析】

  • 系统分析出各个类别的最新或最热点信息条目并组织成set集合,随机挑选其中部分信息
  • 配合用户关注信息分类中的热点信息组织展示的全信息集合

【实战】

应用于随机推荐类信息检索,例如热点歌单推荐,热点新闻推荐,热点旅游线路,应用APP推荐,大V推荐

(2)业务场景2——共同好友

【解决方案】

  • 求两个集合的交、并、差集
    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 应用于同类信息的关联搜索,二度关联搜索,深度关联搜索

  • 显示共同好友,共同关注(一度)
  • 由用户A出发,获取到好友用户B的好友信息列表
  • 由用户A出发,获取到好友用户B的购物清单列表/游戏充值列表
(3)业务场景3——同类型不重复数据的合并操作

【解决方案】
依赖set集合数据不重复的特征,依赖set集合hash存储结构特征完整数据过滤与快速查询

  • 根据用户id获取用户所有角色
  • 根据用户所有角色获取用户所有操作权限
  • 根据用户所有角色获取用户所有数据,这种耦合度太高

【实操】

(4)业务场景4——访问量统计去重

【解决方案】
针对不同的统计类型有不同的数据存储方式
  • 建立String类型数据,利用incr统计日访问量(PV)
  • 建立Set模型,记录不同cookie数量(UV)和不同IP数量(IP)
(5)业务场景5——黑白名单

(五)Sort_Set

【基本操作】

  1. 添加数据:zadd key score1 member1 [score2 member2]
  2. 按照从小到大的顺序,加上withscores,就会带上scores一起显示: zrange key start stop [withscores]
  3. 按照从大到小的顺序:zrevrange key start stop [withscores]
  4. 删除数据:zrem key member [member...]
  5. 查询scores在某个范围内的值:zrangebyscore key min max [withscore] [limit]
  6. 查询key某个索引范围内的值:zrevrangebyscore key max min [withscore]
  7. 删除有序集合中给定索引区间的所有成员:zremrangebyrank key start stop
  8. 删除指定分数区间的所有成员:zremrangebyscore key min max

【实战】

  1. 获取集合数据总量,两个集合求值等
    zcard key #获取总量
    zcount key min max # 获取某一范围的总量
    Zinterstore destination numkeys key [key...] #求和,其中numkeys指定集合(key...)的数量
    zunionstore destination numkeys key [key...]
    

【实操】

【小结】

  • min , max用于限定搜索查询的条件
  • start,stop作用于索引,表示开始和结束索引
  • offset与count用于限定查询范围,作用于查询结构,表示开始位置和数据总量
(1)业务场景1——TOP10排行榜
  1. 票选10大杰出青年,各类综艺选秀海选投票
  2. 各类资源网站TOP10(电影,歌曲,文档,电商,游戏等)
  3. 聊天室活跃度统计
  4. 游戏好友亲密度

【用法】

  1. 正数第几位:zrank key member
  2. 倒数第几位:zrevrank key member
  3. 获取:zscore key member
  4. score递增 increment:zincrby key increment member
(2)业务场景2——会员短期体验之过期失效

参考资料
b站黑马教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值