二、Redis数据存储类型

一、业务数据的特殊性

1.1 怎样的数据作为缓存使用呢?

  1. 原始业务功能设计
  • 秒杀
  • 618活动
  • 排队活动
  • ……
  1. 运营平台监控到的突发高频访问数据
  • 突发时政要闻、被强势关注围观
  • ……
  1. 高频、复杂的统计数据
  • 在线人数(直播等)
  • ……
  1. 系统功能优化或升级
  • 单服务器升级集群
  • Session 管理
  • Token管理

1.2 Redis 数据类型(5种常用)

  • String (类似java-String)
  • hash (类似java-HashMap)
  • list (类似java-LinkedList)
  • set (类似java-HashSet)
  • sorted_set (类似java-TreeSet)

1.3 Redis 数据存储格式

  • Redis自身是一个Map,里面所有的数据都是采用key:value的形式存储
  • 数据类型指的是存储的数据的类型,就是value部分的类型,而key部分永远都是字符串的形式
  • string 最常用的数据存储类型,一个存储空间保存一个数据,通常使用的是字符串,如果字符串以整数的形式展示,可以作为数字操作使用

二、 string类型数据的基本操作

2.1 基本操作

  1. 添加/修改 数据
set key value
  1. 获取数据
get key
  1. 删除数据
del key

示例:
在这里插入图片描述


  1. 添加/修改多个数据
mset key1 value1 key2 value2 ......
  1. 获取多个数据
mget key1 key2 .....

在这里插入图片描述

再对b进行添加的话,就是对他进行修改了在这里插入图片描述


  1. 获取数据字符个数(字符串长度)
strlen key
  1. 追加信息到原始信息后部(如果原始信息存在就追加,否则新建。)
append key value

在这里插入图片描述


2.2 string数据类型的扩展操作

2.21 业务场景一

  • 在大型企业级应用中,分表操作是基本操作,使用多张表存储同类型的数据,但是主键id必须保证统一性,不能重复,Oracle中有sequence设定,MySQL对这一问题该如何解决呢?
    可以利用Redis来解决。
    解决思路:
  1. 设置数值数据增加指定范围的值
 incr key
 incrby key increment
 incrbyfloat key increment   //用于有小数的数据
  1. 设置数值数据减少指定范围的值
decr key
decrby key increment

示例1

设置key = num ,value = 1,incr 默认增加 1。
在这里插入图片描述
decr 默认减少1。
在这里插入图片描述


示例2

设置指定增加范围为 3
在这里插入图片描述
减少范围为 2
在这里插入图片描述

示例3
带小数增加 1.5
在这里插入图片描述


值得注意的是:

  1. string在redis中默认是字符串,遇到incr、decr增减类操作时,会转成数值型进行计算
  2. redis所有操作都是原子性的,并且采用单线程除了所有的业务,命令一个一个的执行,操作a的时候不会操作b,不需要考虑并发的问题
  3. 按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis 数值上限范围,将报错
    总结:
    redis用于控制数据库表主键id,为数据库主键提供生成策略,保障数据库表的主键唯一性,适用于所有数据库,并且支持数据库集群

2.22 业务场景二

  • 新闻网站会有热点新闻,而新闻的特征就是时效性,如何控制热点新闻的时效性呢?
  • 某电商有热门商品,但不能一直处于热门其,热门期只维持1天,1天后取消热门,如何考虑呢?
    解决思路
    Redis 控制数据的生命周期。
    设置具有指定生命周期的数据,当时间到了后,抹除数据。
    命令
 setex key seconds value      //设置某数据生命周期是多少秒
 psetex key milliseconds value    //设置某数据生命周期是多少毫秒

示例:
设置key = Adi 生命周期为10s,10s过后,Adi被抹除
在这里插入图片描述

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


2.23 业务场景三

  • 主页高频访问信息显示控制,如新浪微博大V主页显示粉丝数与微博数量、贴吧等

解决方案:

key 的设置约定:

表名主键名主键值字段名
orderid00010name
equipid0001234type
newid140011title
  • 在redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定定时刷新策略即可
    key → value
    eg: user: id : 3506728370:fans → 12210947
    eg: user : id : 3506728370:blogs → 6164
    eg: user: id :3506728370:focuss → 83

  • 在redis中以json格式存储大V用户信息,定时刷新(也可以使用hash类型)
    eg: user : id : 3506728370 →
    {“id”:3506728370,“name”:“春晚”,“fans”:12210862,“blogs”:6164, “focus”:83}

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


注意:

  1. 表示运行结果是否成功
  • (integer) 0 → false 失败
  • (integer) 1 → true 成功
  1. 表示运行结果值
  • (integer) 3 → 3 3个
  • (integer) 1 → 1 1个
  1. 数据未获取到
    (nil) 等同于 null
  2. 数据最大存储量
    512MB
  3. 数值计算最大范围(java中的ling 的 最大值)
    9223372036854775807

三、 hash类型

3.1存储的问题

对象类数据的存储如果具有较频繁的更新需求操作会显得笨重
如下:
eg: user : id : 3506728370 →
{“id”:3506728370,“name”:“春晚”,“fans”:12210862,“blogs”:6164, “focus”:83}

更新一个字段,操作会很麻烦,那么如何灵活的操作一个字段的信息呢?
答案是有的,使用hash类型
如下图,使用hash类型存储的结构特点。
在这里插入图片描述

存储特点:

  • 方便对数据进行管理
  • 一个存储空间保存多个键值对数据
  • hash类型-底层使用hash表结构实现数据存储
  • 可以优化的地方:
    (1)如果field数量较少,存储结构优化为类数组结构
    (2)如果field数量较多,存储结构使用HashMap结构

3.2 hash类型基本操作

  1. 添加/修改数据:
hset key field value
  1. 获取数据:
hget key field  //获取一个
hgetall key  //获取多个
  1. 删除数据
hdel key field1 [field2] ....  //删除一个或多个

示例:
在这里插入图片描述


  1. 添加/修改多个数据
hset key field1 value1 field2 value2 ...
  1. 获取多个数据
hmget key field1 field2 ...
  1. 获取哈希表中字段的数量
hlen key
  1. 获取哈希表中是否存在指定的字段
hexists key field

示例:
在这里插入图片描述
在这里插入图片描述

3.3 hash类型数据扩展操作

  1. 获取哈希表中所有的字段名或字段值
hkeys key
hvals key 
  1. 设置指定字段的数值数据增加指定范围的值
hincrby key field increment
hincrbyfloat key field increment. 

示例:
获取animal的字段名和字段值
在这里插入图片描述
设置age的增长范围
在这里插入图片描述


注意:

  • hash类型中value只能存储字符串,不能嵌套,如数据未获取,对应的值为 (nil)
  • 每个hash能存储 2^32-1 个键值对
  • hash设计初衷不是为了存储大量对象而设计的,不能滥用,更不可以将hash作为对象列表使用
  • hgetall 操作可以获取全部属性,如果内部field过多,遍历整体数据效率就很会低,有可能成为数据访问瓶颈

3.4 应用场景1 购物车的实现

仅分析购物车的redis存储模型:添加、浏览、更改数量、删除、清空

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

把购物车中的商品记录保存成两条field

  1. field1 用于保存购买数量
    命名格式: 商品id:nums
    保存数据: 数值
  2. field2 用于保存购物车中显示的信息,包含文字描述,图片地址,所属商家信息(独立hash)
    命名格式:商品id:info
    保存数据:json

用户:user-001,商品001数量(filed):100 ,商品001信息:json串
在这里插入图片描述
在这里插入图片描述

命令:

hset key field value

用于给指定key添加数据,已经存在的字段,不会再添加

  • 添加商品002数量为200,
    在这里插入图片描述

  • 已经存在字段 goods-001:nums,所以新的数量 666不能添加
    在这里插入图片描述

  • 如需添加,需要重新set
    在这里插入图片描述

四、list类型

4.1 list类型

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

在这里插入图片描述

如何体现顺序呢?
可以在前后添加和删除
在这里插入图片描述

4.2 list类型基本操作

  1. 添加/修改数据
lpush key value1 [value2] .....  //从左边添加数据
rpush key value1 [value2] .....  //从右边添加数据
  1. 获取数据
lrange key start stop  //查询第i个到第j个之间的数据(索引)
lindex key index   //查询某个数据
llen key   //查询长度

查询全部

lrange key 0 -1
  1. 获取并移除数据
lpop key   //从左边开始移除数据
rpop key   //从右边开始移除数据

示例:

  • 从左往右添加数据,首先添加的时02 然后添加03,查出来的索引元素值第0个是03,如果从左往右添加多个数据,是从第一个数据开始添加。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 从右往左添加数据

在这里插入图片描述

  • 查询长度
    在这里插入图片描述

  • 移除数据 从左往右移除 和 从右往左移除
    在这里插入图片描述


  1. 规定时间内获取并移除数据
    b是 block 阻塞
    timeout 秒
blpop key1 [key2] timeout
brpop key1 [key2] timeout
brpoplpush source destination timeout

  1. 移除指定的数据
lrem key count value  //count 是移除当前元素的个数 从前往后移除

示例:
移除当前元素的一个
在这里插入图片描述
移除当前元素的多个

在这里插入图片描述
在这里插入图片描述

如点赞,取消点赞,点赞时,可以一个一个的添加赞,你想取消点赞了不可能用lpop来移除吧?


总结:

  1. redis应用于具有操作先后顺序的数据控制,如消息队列,任务队列。
  2. redis 应用于最新消息展示。如新闻最新的消息,发布的新商品

五、set类型

5.1 set类型

  • 新的存储需求:使用list的话,因为底层是链表,查询的时候慢,而使用set存储大量的数据,在查询方面提供更高的效率
  • 需要的存储结构:能够保存大量的数据,高效的内部存储机制,便于查询
  • set类型:与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的

结构图解:
在这里插入图片描述

5.2 set类型基本操作

  1. 添加数据
sadd key member1 [member2] ....
  1. 获取数据
smembers key
  1. 删除数据
srem key member1 [member2] 
  1. 获取集合数据总量
scard key
  1. 判断集合中是否包含指定数据
sismember key member

示例:

  • 添加、查询数据
    在这里插入图片描述

  • 删除数据
    在这里插入图片描述

  • 获取集合数据总量,并判断是否包含zs
    在这里插入图片描述
    在这里插入图片描述

5.3 set类型数据扩展操作

5.31 业务场景一

业务场景
如某些应用首次启动时,会让选择感兴趣的内容,但是到了后期为了增加用户的活跃度、黏性等,必须让用户对其他信息类别逐渐产生兴趣,这时候如何实现呢?还有如热点新闻推荐、歌单推荐等如何实现呢?

业务分析

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

解决方案

  1. 随机获取集合中指定数量的数据(原数据总量不会发生改变,拿出多少个都不会影响总量)
srandmember key [count]
  1. 随机获取集合中的某个数据并将该数据移除集合(原数据会发生改变,拿了几个数据就少几个数据)
spop key [count]

示例:

  1. 设置4条新闻,拿出2条推荐个用户
    在这里插入图片描述

总数没有发生改变
在这里插入图片描述

  1. 拿出数据后,数据总量会发生改变。
    在这里插入图片描述

5.32 业务场景二

业务场景
在很多社交软件中,经常会出现推荐好友,这是如何实现的呢?新用户基本没什么好友,如何快速帮助用户积累好友为社交软件带来更多的活跃度呢?
美团饿了么为了提升成单量,必须帮助用户挖掘美食需求,如何推荐给用户最适合自己的美食?

解决方案:

  1. 求两个集合的交集
sinter key1 [key2]
  1. 并集
sunion key1 [key2]
  1. 差集
sdiff key1 [key2]

  1. 求两个集合的交、并、差集并存储到指定集合中
sinterstore destination key1 [key2]   //交集 destination指定集合。
sunionstore destination key1 [key2]   //并集
sdiffstore destination key1 [key2]    //差集
  1. 将指定数据从原始集合中移动到目标集合中
smove source destination member

示例:

设置两个集合a1:{01 ,02 ,03},b1:{01 , 04}
在这里插入图片描述

交集:

在这里插入图片描述
并集:
在这里插入图片描述
差集(a1-b1):
在这里插入图片描述

把a1和b1的交集存储到c1中
在这里插入图片描述
把02移到b1
在这里插入图片描述


总结:

  1. set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份
  2. set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间
  3. redis 应用于同类信息的关联搜索,二度关联搜索,深度关联搜索

应用方面:

  • 显示共同关注(一度)
  • 显示共同好友(一度)
  • 由用户A出发,获取到好友用户B的好友信息列表(一度)
  • 由用户A出发,获取到好友用户B的购物清单列表(二度)
  • 由用户A出发,获取到好友用户B的游戏充值列表(二度)

六 、sorted_set类型

6.1 sorted_set类型

  • 新的存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式,新的存储模型,可以保存可排序的数据
  • sorted_set类型:在set的存储结构基础上添加可排序字段

结构图解:
在这里插入图片描述

6.2 基本操作

  1. 添加数据
zadd key score1 member1 [score2 member2]
  1. 获取全部数据
zrange key start stop [WITHSCORES]
zrevrange key start stop [WITHSCORES]
  1. 删除数据
zrem key member [member ...]

示例:

添加数据:
在这里插入图片描述

获取数据(升序):
在这里插入图片描述

获取(降序):
在这里插入图片描述

删除数据:
在这里插入图片描述


  1. 按条件获取数据
zrangebyscore key min max [WITHSCORES]  [LIMIT]  //min、max,最小最大区间
zrevrangebyscore key max min  [WITHSCPRES]
  1. 按条件删除数据
zremrangebyrank key start stop
zremrangebyscore key min max

注意:

  • min与max用于限定搜索查询的条件
  • start与stop用于限定查询范围,作用于索引,表示开始和结束索引
  • offset与count用于限定查询范围,作用于查询结果,表示开始位置和数据总量

  1. 获取集合数据总量
zcard key
zcount key min max
  1. 集合交、并操作
zinterstore destination numkeys key [key ...]
zunionstore destination numkeys key [key ...]

七、redis通用操作

7.1 key通用指令

7.11 key的基本操作

key的特征

  • key是一个字符串,通过key获取redis中保存的数据

key应该设计哪些操作?

  • 对于key自身状态的相关操作,例如:删除,判定存在,获取类型等
  • 对于key有效性控制相关操作,例如:有效期设定,判定是否有效,有效状态的切换等
  • 对于key快速查询操作,例如:按指定策略查询key
  • ……

key基本操作:

  1. 删除指定key
del key
  1. 获取key是否存在
exists key
  1. 获取key的类型
type key

  1. 为指定key设置有效期
expire key seconds  //秒
pexpire key milliseconds  //毫秒
expireat key timestamp   //时间戳
pexpireat key milliseconds-timestamp
  1. 获取key的有效时间
ttl key
pttl key

注意:
获取的结果中 -2表示key已经时间失效,-1表示没有设置有效时间或者有效时间设置成永久,具体时间的话就是key还处于有效时间内

  1. 切换key从时效性转换为永久性
persist key

  1. 查询key:
keys pattern

查询模式规则
匹配任意数量的任意符号 *
配合一个任意符号 ?
匹配一个指定符号 []

keys * 查询所有
keys aa* 查询所有以aa开头
keys *aa 查询所有以aa结尾
keys ??aa 查询所有前面两个字符任意,后面以aa结尾
keys user:? 查询所有以user:开头,最后一个字符任意
keys u[st]er:1 查询所有以u开头,以er:1结尾,中间包含一个字母,s或t

  1. 为key改名
rename key newkey   //如果已经存在一个key,改名成这个key,原来的key会被覆盖
renamenx key newkek  //如果已经存在一个key,改名成这个key,会提示失败
  1. 对所有key排序
sort  //   对可以排序的类型的数据进行排序,不会改变原来数据的顺序
  1. 其他key通用操作
help @generic

7.2 数据库通用操作

key 的重复问题

  • key是由程序员定义的
  • redis在使用过程中,伴随着操作数据量的增加,会出现大量的数据以及对应的key
  • 数据不区分种类、类别混杂在一起,极易出现重复或冲突

解决方案

  • redis为每个服务提供有16个数据库,编号从0到15
  • 每个数据库之间的数据相互独立(但共用一个空间)
    在这里插入图片描述

db基本操作

  1. 切换数据库(0-15)
select index
  1. 其他操作
quit   //退出
ping  //测试连接
echo message //打印消息

  1. 数据移动
move key db   //把key移到某一个db数据库中
  1. 数据清除
dbsize  //返回当前数据库的 key 的数量
flushdb  //清空当前数据库中的所有 key
flushall  //清空整个 Redis 服务器的数据(删除所有数据库的所有 key )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值