栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2022/08/04、05 day01-2/02:Redis数据类型

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2022/08/04、05 day01-2/02:Redis数据类型

文章目录
  • 今日内容
  • 数据存储类型介绍
  • string
    • **Redis数据存储格式**
    • **string类型**
    • **string类型数据的基本操作**
    • **string类型数据的扩展操作**
    • **string类型数据操作的注意事项**
    • **string类型应用场景**
    • **key的设置约定**
  • hash
  • list

今日内容

常用的数据类型一共有一下5种:

  1. string
  2. hash
  3. list
  4. set
  5. sorted_set
  6. 数据类型实践案例
数据存储类型介绍

业务数据的特殊性

  • 作为缓冲使用
  1. 原始业务功能设计
    1. 秒杀
    2. 京东618活动
    3. 天猫双11活动
    4. 火车排队购票
  2. 运营平台监控到的突发高频访问数据
    1. 突发时政要闻,被强势关注围观
  3. 高频、复杂的统计数据
    1. 在线人数
    2. 投票排行榜
  • 附加功能
  1. 系统功能优化或升级
    1. 单服务器升级集群
    2. Session管理
    3. Token管理

Redis数据类型(5种常用)

  1. string
  2. hash
  3. list
  4. set
  5. sorted_set
string Redis数据存储格式
  1. Redis自身是一个Map,其中所有的数据都是采用key:value的形式存储
  2. 数据类型指的是存储的数据的类型,也就是value部分的类型,key部分永远都是字符串
string类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2NBOyzvI-1659702772759)(en-resource://database/4938:1)]

  1. 存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型
  2. 存储数据的格式:一个存储空间保存一个数据
  3. 存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用,但其本质还是字符串
string类型数据的基本操作
  1. 添加/修改数据:set key value
    1. 添加/修改多个数据:mset key1 value1 key2 value2…
    2. 追加信息到原始信息后部(如果原始信息存在就追加,否则新建):append key value
  2. 获取数据:get key
    1. 获取多个数据:mget key1 key2…
    2. 获取数据字符个数(字符串长度):strlen key
  3. 删除数据:del key
    1. (integer) 0 代表失败
    2. (integer) 1 代表成功
string类型数据的扩展操作

业务场景
大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键id必须保证统一性,不能重复。Oracle数据库具有sequence设定,可以解决该问题,但是MySQL数据库并不具有类似的机制,那么该如何解决呢?

解决方案:

  1. 设置数值数据增加指定范围的值
    1. incr key 如果是数值,则给value做增操作,每次增加1个单位
    2. incrby key increment 增加指定的整数的值(可以为负数)
    3. incrbyfloat key increment 增加指定的小数的值
  2. 设置数值数据减少指定范围的值
    1. decr key 如果是数值,则给value做减操作,每次减少1个单位
    2. decrby key increment 减少指定的整数的值(可以为负数)

string作为数值操作

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

Tips 1:

  1. redis用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性
  2. 此方案适用于所有数据库,且支持数据库集群

业务场景

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

解决方案

  1. 设置数据具有指定的生命周期
    1. setx key seconds value 秒
      1. 例如:setex tel 10 1 当10s到达后,tel就失效为空了(没有了)
      2. 例如:set tel 2 此命令已经更新,上面的语句已经没有用了
    2. psetex key milliseconds value 毫秒
      1. 例如:psetex tel 9999 1

Tips 2:
redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作

string类型数据操作的注意事项
  1. 数据操作不成功的反馈与数据正常操作之间的差异
    1. 表示运行结果是否成功
      1. (integer) 0 -> false 失败
      2. (integer) 1 -> true 成功
    2. 表示运行结果值
      1. (integer) 3 -> 3 3个
      2. (integer) 1 -> 1 1个
    3. 数据为获取到
      1. (nil) 等同于null 不存在
      2. 数据最大存储量
        • 512MB
    4. 数值计算最大范围(java中的long的最大值)
      • ±9223372036854775807
string类型应用场景

业务场景

  1. 主页高频访问信息显示控制。
    1. 例如新浪微博大V主页显示粉丝数与微博数量

解决方案

  1. 在Redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定定时刷新策略即可。
    1. eg: user3506728370:fans → 12210947
    2. eg: user3506728370:blogs → 6164
    3. eg: user3506728370:focuss → 83
      1. 例子:set user00789:blogs 789
      2. 例子:set user:id00789:fans 123456789
  2. 在Redis中以json格式存储大V用户信息,定时刷新(也可以使用hash类型)
    • eg: user3506728370 →
      {“id”:3506728370,“name”:“春晚”,“fans”:12210862,“blogs”:6164, “focus”:83}
    • 例子:set user00789 {id:00789,blogs:789,fans:999}
    • 使用这种方式: incr user00789:blogs --> (integer) 790

Tips 3:
redis应用于各种结构型和非结构型高热度数据访问加速

key的设置约定
  • 数据库中的热点数据key命名规范
hash

存储的困惑

hash类型

  1. 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息
  2. 需要的存储结构:一个存储空间保存多个键值对数据
  3. hash类型:底层使用哈希表结果实现数据存储

hash类型数据的基本操作

  1. 添加/修改数据
    1. hset key field value
      1. 例子:hset user name zhangsan
      2. 例子:hset user age 38
      3. 例子:hser user weight 80
  2. 获取数据
    1. hget key field
      1. 单查询:hget user name
    2. hgetall key
      1. 全查询:hgetall user
  3. 删除数据
    1. hdel key field1 [field2]
      1. 删除weight:hdel user weight
  4. 添加/修改多个数据
    1. hmset key field1 value1 field2 value2…
    2. 例子:hmset user name zhangsanfeng weight 68 已经有的就改了,没有的就加上去了。
  5. 获取多个数据
    1. hmget key field1 field2…
    2. 例子:hmget user name age -->纯值
  6. 获取哈希表中字段的数量
    1. hlen key
    2. 例子:hlen user 看的是field的字段
  7. 获取哈希表中是否存在指定的字段
    1. hexists key field
    2. 例子:hexists user age – (integer) 1 true
    3. 例子:hexists user hight – (integer) 0 false

hash类型数据扩展操作

  1. 获取哈希表中所有字段名或字段值
    1. hkeys key
      1. 例子:hkeys user 打印field
    2. hvals key
      1. 例子:hvals user 打印value
  2. 设置指定字段的数值数据增加指定范围的值
    1. hincrby key field increment
      1. 例子: hincrby user age 2 value字段增加整数范围内的值
    2. hincrbyfloat key field increment
      1. 例子:hincrbyfloat user age 1.1 value字段增加小数范围内的值

hash类型数据操作的注意事项

  1. hash类型下的value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到对应的值为(nil)
  2. 每个hash键值对式有上限的,可以存储2^32 -1个键值对
  3. hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性,但hash设计初衷不是为了存储大量对象设计的,切记不可滥用,更不可以将hash作为对象列表使用(随着对象存储的增多,会很麻烦,效率会很低)
  4. hgetall操作可以获取全部属性,如果内部field过多,遍历整体数据效率就会很低,有可能成为数据访问瓶颈

hash类型应用场景
业务场景
电商网站购物车设计与实现

业务分析

  1. 仅分析购物车的Redis存储模型
    1. 添加、浏览、更改数量、删除、清空
  2. 购物车于数据库间持久化同步(不讨论)
  3. 购物车于订单间的关系(不讨论)
    1. 提交购物车:读取数据生成订单
    2. 商家临时价格调整:隶属于订单级别
  4. 未登录用户购物车信息存储(不讨论)
    1. cookie存储

解决方案

  1. 以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息
  2. 将商品编号作为field,购买数量作为value进行存储
  3. 添加商品:最佳全新的field与value
  4. 浏览:遍历hash
  5. 更改数量:自增/自减,设置value的值
  6. 删除商品:删除field
  7. 清空:删除key

购物车实现

  1. 用户001 商品g01 g02
    1. hmset 001 g01 100 g02 200
  2. 用户002 商品g02 g04 g05
    1. hmset 002 g02 1 g04 7 g05 100
  3. 给001用户添加一个商品 g03 添加field
    1. hset 001 g03 5
  4. 查看用户001的所有商品
    1. hgetall 001
  5. 用户001 的g01商品不要了 删除field
    1. hdel 001 g01
  6. 用户001 的 g03商品 在加10个 添加field对应的值
    1. hincrby 001 g03 10

提问:我们当前的设计是否加速了购物车的呈现?
当前仅仅是将数据存储到了Redis中,并没有起到加速的作用,商品信息还需要二次查询数据库。

  • 每条购物车中的商品记录保存成两条field
  • field1专用与保存购买数量
    • 命名规则:商品ID:nums
    • 保存数据:数值
  • field2 专用于保存购物车中显示的信息,包含文字描述,图片地址,所属商家信息等
    • 命名格式:商品ID:info
    • 保存数据:json

实现

  1. 用户003 商品信息 json
    1. hmset 003 g01:nums 100 g01:info {…}
    2. 查看一下:hgetall 003
  2. 用户004 商品信息
    1. hmset 004 g01:nums 5 g01:info {…} 与003用户命令差不太多
    2. 查看一下:hgetall 004
  3. 出现问题:大量的信息重复
    1.
    2. hsetnx key field value key中的field如果存在,就无效(不动),不存在则生效(创建)
  4. 独立hash,提升速度效率

Tips 4:
redis 应用于购物车数据存储设计

业务场景
商家的东西

  • 双11活动日,销售手机充值卡的商家对移动、联通、电信的30元、50元、100元商品推出抢购活动,每种商品抢购上限1000张。

解决方案

  • 以商家ID作为key
  • 将参与抢购的商品ID作为field
  • 将参与抢购的商品数量作为对应的value
  • 抢购时使用降值的方式控制产品数量
  • 实际业务总还有超卖等实际问题,这里不做讨论

实现

  1. 设置抢购的商品
    1. hmset p01 c30 1000 c50 1000 c100 1000
  2. 假设有一个人买到了一张,p50卡
    1. hincrby p01 c50 -1
  3. 大老板购买p100的20张
    1. hincrby p01 c100 -20
  4. 查看商品售卖情况
    1. hgetall p01

Tips 5:
redis 应用于抢购,限购类、限量发放优惠卷、激活码等业务的数据存储设计

业务场景

  • string存储对象(json)与hash存储对象
    • string讲究一次性,讲究读
    • hash有一个分隔(field)讲究的是更新
list

list类型

  • 数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
  • 需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序
  • list类型:保存多个数据,底层是用双向链表存储结构实现

list 类型数据基本操作

  • 添加/修改数据
    1. lpush key value1 [value2] … 从左边进
      1. 例子:lpush list1 huawei
      2. lpush list1 apple
      3. lpush list1 microsoft
    2. rpush key value1 [value2] … 从右边进
      1. 例子: rpush list2 a b c
  • 获取数据
    1. lrange key start stop list有索引,start stop指的是索引 从n开始,从m结束
      1. 例子: lrange list1 0 4
      2. lrange list1 0 -1 这就可以看完
    2. lindex key index index代表的是索引
      1. 例子:lindex list1 0 0号索引是什么?
    3. llen key
      1. 例子:llen list1
  • 获取并移除数据
    1. lpop key 从左边出(把key中的元素拿出来)
      1. 添加数据:lpush list3 a b c
      2. 拿出数据:lpop list3 --> c
      3. 查字段:llen list3 --> 2
    2. rpop key
      1. 向右拿出数据: rpop list3 --> a
      2. 查字段: llen list3 --> 1

list 类型数据扩展操作

  • 规定时间内获取并移除数据
    1. blpop key1 [key2] timeout
    2. brpop key1 [key2] timeout
    3. 例子:
      1. 添加数据: lpush list0 a b
      2. 拿出数据:lpop list0
      3. 阻塞版本:我可以等[30s]
        1. blpop list0 10 [key …] timeout
        2. 能拿出来(key中存在)就拿出来,等效于lpop
        3. 不能拿出来就会等待(阻塞) 之后返回nil 或者直到key中存在,然后马上把它取出来

业务场景

  • 微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息
  • 如果取消点赞,移除对应的好友信息

解决方案

  • 移除指定数据
    • lrem key count value
    • l表示从左边删除 count代表个数 value删除哪个东西

实现

  • 进来5个人
    • rpush 005 a b c d e
  • 查看那些人
    • lrange 005 0 -1
  • 现在c取消点赞了 动了中间的
    • lrem 005 1 c
  • 再加点东西
    • rpush 005 a b a b a c e
  • 删除3个a
    • lrange 005 0 -1

Tips 6:
redis 应用于具有操作先后顺序的数据控制

list 类型数据操作注意事项

  • list中保存的数据都是string类型的,数据总容量是有限的,最多2^32-1个元素(4294967295)
  • list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作
  • 获取全部数据操作结束索引设置为-1
  • list可以对数据进行分页操作,通常第一页的信息来自于list,第二页及更多的信息通过数据库形式加载

list 类型应用场景

业务场景

  • Twitter、新浪微博、腾讯微博中个人用户的关注列表需要按照用户的关注顺序进行展示,,粉丝列表需要将最近的粉丝列在前面

  • 新闻、资讯类网站如何将最新的新闻或资讯按照发生的时间顺序展示?

  • 企业运营过程中,系统将产生出大量的运营数据,如何保障多台服务器操作日志的统一顺序输出?

解决方案

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

实现
Redis充当的是汇总的角色,非常好的是它有顺序

  • 窗口1
    • rpush logs a1
    • rpush logs a1…
    • lrange logs 0 -1
  • 窗口2
    • rpush logs b1
    • rpush logs b1…
  • 窗口3
    • rpush logs c1
    • rpush logs c1…

Tips 7:
redis 应用于最新消息展示

                                                                                 ——此文档为学习笔记!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1035690.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号