Redis学习笔记-数据类型
2021/11/9 19:40:37
本文主要是介绍Redis学习笔记-数据类型,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
概述
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。
本文讨论常用的五个数据类型:字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)。
- Redis 自身是一个 Map,其中所有的数据都是采用 key : value 的形式存储
- 数据类型指的是存储的数据的类型,也就是 value 部分的类型,key 部分永远都是字符串
字符串(strings)
- 存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型
- 存储数据的格式:key:str
- 存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用
存储空间:
key | value |
---|---|
key1 | itinfo |
key2 | redis |
string的基本操作
用处 | 语法 |
---|---|
添加/修改数据 | set key value |
获取数据 | get key |
删除数据 | del key |
添加/修改多个数据 | mset key1 value1 key2 value2 …(multiple) |
获取多个数据 | mget key1 key2 … |
获取数据字符个数(字符串长度) | strlen key |
追加信息到原始信息后部(如果原始信息存在就追加,否则新建) | append key value |
-
get 、set
- -
mget、mset
不存在的key显示nil -
strlen、append
set和mset的底层差异
指令 --------> Redis(t1)
Redis处理数据(t2)
指令 <-------- Redis(t3)
n个数据的情况:
set: n*(t1+t2+t3)
mset: t1+t3+n*t2
set总体时间多:(n-1)*(t1+t3)
扩展操作
用处 | 语法 |
---|---|
设置数值数据增加指定范围的值 | incr key 、incrby key increment 、 incrbyfloat key increment |
设置数值数据减少指定范围的值 | decr key 、decrby key increment |
设置数据具有指定的生命周期 | setex key seconds value、psetex key milliseconds value |
上例中设置key-ccie的生命周期为8秒,8秒后ccie被移除
Tips
- 数据操作成功与否的反馈与数据正常操作之间的差异
- 表示运行结果是否成功
(integer) 0 → false 失败
(integer) 1 → true 成功- 表示运行结果值
(integer) 3 → 3个
(integer) 1 → 1个
- 数据未获取到
(nil)等同于null - 数据最大存储量512MB
- 数值最大范围(与java中的long的最大值一致)9223372036854775807
string业务场景
- 微信投票,每个微信号每 4 小时只能投1票。
可以使用为key设置生命周期,定义微信号为key,value为投票,生命周期为4小时
setex WeiXinID:12384932xx09 14400 No28
- 企业数据库分表操作是基本操作,使用多张表存储同类型数据,但是对应的**主键 id **必须保证统一性,不能重复。Oracle 数据库具有 sequence 设定,可以解决该问题,但是 MySQL数据库并不具有类似的机制
Redis利用incr key 、incrby key increment 用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性。
这是因为:
- string在Redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算。
- Redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响。
- 主页高频访问信息显示,例如微博大V主页显示粉丝数与微博数量
在Redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定定时刷新(也可以使用hash)
user: id:3506728370:fans 65535
user: id:3506728370:follow 78
数据库中的热点数据key命名惯例,key 的设置约定
表名 :主键名 :主键值 :字段名
如-order :id :390472345 :name
散列(hashes)
如上的大V主页的例子,使用str数据类型显得太过于笨重,需要对一系列存储的数据进行编组,方便管理。这个时候可以使用Hash散列。
- 一个存储空间保存多个键值对数据
- 底层使用哈希表结构
Hash的基本操作
功能 | 语法 |
---|---|
添加/修改数据 | hset key field value |
添加/修改数据,之前检查是否存在 | hsetnx key field value |
获取数据 | hget key field、hgetall key |
删除数据 | hdel key field1 [field2] |
添加/修改多个数据 | hmset key field1 value1 field2 value2 … |
获取多个数据 | hmget key field1 field2 … |
获取哈希表中字段的数量 | hlen key |
获取哈希表中是否存在指定的字段 | hexists key field |
获取哈希表中所有的字段名或字段值 | hkeys key、hvals key |
设置指定字段的数值数据增加指定范围的值 | hincrby key field increment、hincrbyfloat key field increment |
Tips
- hash类型下的value只能存储字符串,不允许存储其他数据类型
- 不存在嵌套现象
- 如果数据未获取到,对应的值为(nil)
- hash类型十分类似对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,切记不可滥用,更不可以将hash作为对象列表使用
- hgetall 操作可以获取全部属性,如果内部field过多,遍历整体数据效率就很会低,有可能成为访问瓶颈
- 每个 hash 可以存储 2^32 - 1 个键值对
Hash业务场景
- 电商网站购物车设计与实现
- 以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息
- 将商品编号作为field1,购买数量作为value进行存储
- 商品描述:商品ID作为field2,描述信息作为value,可以使用json格式
- 添加商品:追加全新的field与value
- 浏览:遍历hash
- 更改数量:自增/自减,设置value值
- 删除商品:删除field
- 清空:删除key
- 给定数量不同商品的抢购,如销售手机充值卡时对30元、50元、100元商品推出抢购活动,每种商品抢购上限1000张
- 以商品id作为key
- 将参与抢购的商品id作为field
- 将参与抢购的商品数量作为对应的value
- 抢购时使用降值的方式控制产品数量
列表(lists)
- 多个数据,有顺序
- 底层使用双向链表,两边都可以进出
- key:value1 value2 value3…
顺序表与链表
- 顺序表
表头指针—n1—n2—n3—n4
插入n0
表头指针—n0—n1—n2—n3—n4
- n0后的每个数据要动一下
- 寻址快,变化慢
2.链表
表头指针—>n1—>n2—>n3—>n4
插入n0
表头指针–X-->n1—>n2—>n3—>n4 #断开链接
表头指针—>n0,n1—>n2—>n3—>n4 #链接插入的元素
表头指针—>n0—>n1—>n2—>n3—>n4
只需要改变插入元素前后
变化快,寻址慢
list的基本操作
功能 | 语法 |
---|---|
添加/修改数据 | lpush key value1 [value2] ……、rpush key value1 [value2] …… |
获取数据 | lrange key start stop、lindex key index |
获取元素数量 | llen key |
获取并移除数据 | lpop key、rpop key |
规定时间内获取并移除数据 | blpop key1 [key2] timeout、brpop key1 [key2] timeout |
规定时间内获取并移除数据放入目标队列 | brpoplpush source destination timeout |
移除指定数据 | lrem key count value |
- blpop key timeout
list01已经没有数据的情况下,最后一个10秒内push数据后可以取出。
辅助:
- lrem
Tips
- list中的数据都是string类型,最多2^32- 1 个元素 (4294967295)
- list具有索引的概念,操作数据时通常以队列或栈的形式进行操作
- 获取全部数据操作结束索引设置为-1
- list可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载
list应用场景
- 个人用户的关注列表需要按照用户的关注时间顺序进行展示,粉丝列表需要将最近关注的粉丝列在前
- 企业运营过程中,如何保障多台服务器操作日志的统一按时间顺序输出?
将logs发到同一Redis服务
集合(sets)
- 不重复的大量数据
- 与hash存储结构完全相同,仅存储field键,不存储值(nil),并且值是不允许重复的
set的基本操作
功能 | 语法 |
---|---|
添加数据 | sadd key member1 [member2] |
获取全部数据 | smembers key |
删除数据 | srem key member1 [member2] |
获取集合数据总量 | scard key |
判断集合中是否包含指定数据 | sismember key member |
随机获取集合中指定数量的数据 | srandmember key [count] |
随机获取集合中的某个数据并将该数据移出集合 | spop key [count] |
注意是members,不是member
srandmembers取出后原set不变
spop取出后原set该元素被弹出
set的扩展操作
集合计算
交:A∩B
并:A∪B
差:A-B
功能 | 语法 |
---|---|
求两个集合的交集 | sinter key1 [key2] |
求两个集合的并集 | sunion key1 [key2] |
求两个集合的差集 | sdiff key1 [key2] |
求两个集合的交集并存储到指定集合中 | sinterstore destination key1 [key2] |
求两个集合的并集并存储到指定集合中 | sunionstore destination key1 [key2] |
求两个集合的差集并存储到指定集合中 | sdiffstore destination key1 [key2] |
将指定数据从源集合中移动到目标集合中 | smove source destination member |
注意:集合差有方向性
将set01中的etaon移到set02:
set业务场景
- 每位员工具有一个或多个角色,如何快速进行业务操作的权限校验?
A员工的Role
- 统计网站的PV(访问量),UV(独立访客),IP(独立IP)
相同IP统计冲突,总数为集群元素数量
有序集合(sorted sets)
- 数据大量,有排序的要求
- 新的存储模型,可以保存可排序的数据
- zset:set基础上增加可排序值
sorted_set的基本操作
功能 | 语法 |
---|---|
添加数据 | zadd key score1 member1 [score2 member2] |
获取全部数据 | zrange key start stop [WITHSCORES]、zrevrange key start stop [WITHSCORES] |
删除数据 | zrem key member [member …] |
按条件获取数据 | zrangebyscore key min max [WITHSCORES] [LIMIT]、zrevrangebyscore key max min [WITHSCORES] |
条件删除数据 | zremrangebyrank key start stop、zremrangebyscore key min max |
获取集合数据总量 | zcard key、zcount key min max |
集合交、并操作 | zinterstore destination numkeys key [key …]、zunionstore destination numkeys key [key …] |
注意:
- min与max用于限定搜索查询的条件
- start与stop用于限定查询范围,作用于索引,表示开始和结束
别忘了withscores
- 显示s-set01中score 10到122的元素,且取从第一个索引的前两个:
对比,从第二个索引的前2个
- 元素etaon:88被删除
注意:交、并集后score为相加的结果
set的扩展操作
功能 | 语法 |
---|---|
获取数据对应的索引(排名) | zrank key member、zrevrank key member |
score值获取与修改 | zscore key member、zincrby key increment member |
Tips
- score保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992
- score保存的数据也可以是一个双精度的double值,基于双精度浮点数的特征,可能会丢失精度,使用时候要慎重
- sorted_set 底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被反复覆盖,保留最后一次修改的结果
zset应用场景
-
排行榜或资源排序
实际排名为:zrank结果+1 -
带有权重的任务,优先处理权重高的任务,采用score记录权重。
例如设定外贸订单优先于国内订单,总裁订单优先于员工订单,经理订单优先于员工订单:
- 设置外贸101,国内102,经理004,员工008
- 员工下的外贸单score值为101008(优先)
- 经理下的国内单score值为102004
注意:
- score长度必须是统一的,不足位补0。
- 第一排序规则首位不得是0
- VIP用户到期管理
使用time获得时间数据,设定到期时间
当时间到达时,只需考量排名第一的用户提醒并移除
这篇关于Redis学习笔记-数据类型的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-08阿里云Redis项目实战入门教程
- 2024-11-08阿里云Redis资料:新手入门与初级使用指南
- 2024-11-08阿里云Redis教程:新手入门及实用指南
- 2024-11-07阿里云Redis学习入门:新手必读指南
- 2024-11-07阿里云Redis学习入门:从零开始的操作指南
- 2024-11-07阿里云Redis学习:初学者指南
- 2024-11-06阿里云Redis入门教程:轻松搭建与使用指南
- 2024-11-02Redis项目实战:新手入门教程
- 2024-10-22Redis入门教程:轻松掌握数据存储与操作
- 2024-10-22Redis缓存入门教程:快速掌握Redis缓存基础知识