前言
大家好, ☀ 杭州天气 ☀ 今天阴,温度-6~0℃,西北风5-6级转西北风4-5级,06:57日出,17:14日落。
天冷了,防风保暖,巧搭帽子、围巾、手套既保暖又时尚。
感冒极易发生,避免去人群密集的场所,勤洗手勤通风有利于降低感冒几率。
🍀 寄语 🍀 个人之于社会等于身体的细胞,要一个人身体健全,不用说必须每个细胞都健全。
梦梦酱:
诶,你今天工作是不是很忙啊?看你一整天都不得空,给你发消息也不及时回人家😕
索大:
🤗哈哈,是啊,最近临近年关了,公司各种绩效考核、项目会议,然后我电脑端又没上微信,平时手机看到少,抱歉抱歉。
梦梦酱似乎也没怎么生气:
好吧,我也没什么特别的事,吃过晚饭,我们去健身房活动会吧。
索大:
可以啊。对了,上次和你聊过的Redis 一些基本的概念和安装使用,应该会了吧,那今天给你再复习复习它的一些特性吧。
Redis 基本的数据类型
我们了解了Redis 底层实现的数据结构知之后,再来看Redis 提供API 支持的数据类型,就好理解点了。
首先我们要对Redis 支持的数据类型要有一个直观的感受,这时候可以通过图片来帮助我们理解。
这里提供一个 redis 命令参考,我们不用刻意记住每一个数据类型的操作命令,当需要的时候可以来这查找。
String 数据类型
string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以字符串(简单的字符串、复杂的字符串(xml、json)、数字(整数、浮点数)、二进制(图片、音频、视频).。
string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M。
常用操作命令
01 set :用于给指定的key设置value,支持设置已存在的key
02 get: 用于取指定key的value
03 setnx:用于给指定的key设置value,如果key已经存在则返回0。nx代表:not exist
04 setex:用于给指定的key设置value,并且需要指定该key的有效时间。10秒后则返回为空
05 setrange:给指定的key的值重新覆盖内容,从4指定位置,替换内容为ming,最终结果为xiaoming
06 mset:批量设置key对应的value值,以下设置username、age、sex 分别对应 wangwu、10、1
07 msetnx:批量设置key对应的value值,如果key已存在则返回0。由于以上设置过,则结果返回0
08 getset:给指定key设置新值,并且返回之前原始数据。
09 getrange:返回一个字符串的子字符串,相当于字符串截取,下标0是起始位置,下标3是结尾位置
10 mget:批量获取key对应的value,按顺序展示
11 incr:将指定key中存储的数字值增一,必须是数字类型,否则会返回错误信息
11 incrby:将指定key中存储的数字指定增加多少
12 decr:将指定key中存储的数字值减一,必须是数字类型,否则会返回错误信息
13 decrby:将指定key中存储的数字指定减少多少
14 append:给指定的key中的值追加字符串
15 strlen:返回指定key中value的
应用场景
热点数据缓存,提高访问性能 分布式数据共享,如 session共享 分布式锁,基于 setnx 生成全局ID,基于 -INCRBY 计数器,INCR 流量控制,如访问IP次数限制 位统计,非常节省空间,类似于布隆过滤器的原理
Hash散列数据类型
Redis hash 是一个键值对集合。类似Java里面的Map<String,Object> Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
每个 hash 可以存储 2^32 -1 键值对(40多亿个)。
常用的操作命令
1.hset key field value设置一个散列,但是在散列中一次只能设置一个属性,如果要批量设置多个属性,则需要使用 hmset命令
2.hget key field获取指定key对应的散列中的指定属性对应的值,也是只能每次获取一个属性对应的值,如果要获取批量属性值,则需要使用命令 hmget
3.hmset key field value[(field value)...]设置一个散列,例如:hmset key1 name lonely age 18,该追令会生成一个key为key1的散列,散列中的属性有两个 分别是 name以及age,对应的值分别是 lonely和18
4.hmget key field...返回指定key对应的散列中指定key-name对应的值,例如上例子的基础上,调用 hmget key1 name指令的结果就是 从key1对应的散列中,获取属性 name对应的值 lonely就是结果了
5.hdel key field...删除指定key对应的散列中指定field...的信息。 例如有key1:{name:lonely,age:25},那么使用命令hdel key1 age;的结果是删除了 age属性信息,即 只剩下 key1:{name:lonely}
6.hlen key返回指定key对应的散列中键值对的数量
7.hexists key field 判断指定key对应的散列中是否存在field属性的键值对8.hkeys key 返回指定key对应的散列的key集合,例如存在 key1:{name:lonely,age:25},那么使用hkeys key1命令的结果就是 {name,age}
9.hvals key 同hkeys命令类似,不过hvals命令返回的指定key对应散列的value集合
9.hgetall key 返回指定key对应的所有键值对信息
10.hincrby key field increment 将指定key对应的散列中指定属性对应的value递增increment个单位,注意只有值是数值类型才可以生效,返回递增后
应用场景
Hash哈希结构相对于String字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。
所以存储一些结构化的数据,比如用户的昵称、年龄、性别、积分等,存储一个用户信息对象数据以及购物车。
List列表数据类型
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。
它的底层实际是个链表结构实现的
列表最多可存储 2^32 - 1 个元素 (4294967295, 每个列表可存储40多亿)。
常用命令
01 lpush : 将一个元素或者多个元素新增到列表的头部,返回当前list中元素数量,采用的是 栈。
02 lrange: 返回list集合中指定区间中的元素,0下标代表第一个元素,-1代表最后一个元素。
03 rpush: 将一个元素或者多个元素新增到列表的尾部,返回当前list中元素数量,采用的是 队列。
04 linsert: 在指定列表的元素前或者后插入元素
05 lset: 设置list列表中指定元素下标的值, 下标0代表第一个元素,替换成了bear。
06 lrem: 从对应list列表中删除n和value相同的元素,"lrem list 1 noe"代表在list列表中删除1和noe相同的元素。
07 ltrim: 保留指定key值范围内的数据,已知list列表有三个元素,现在只想保留前两个,最后显示tow已经去掉了
08 lpop: 从列表头部删除一个元素,返回删除的元素值。
09 rpop: 从列表尾部删除一个元素,返回删除的元素值。
10 rpoplpush:从第一个列表尾部移除一个元素并且添加到第二个列表中头部从第一个列表中尾部移除一个元素 ,mylist2尾部的元素elephant,rpop命令干的事往第二个列表的头部添加一个元素,list中的头部添加元素elephant,lpush命令干的事
11 lindex: 返回列表中指定下标的元素值,元素下标0开始
12 llen: 返回列表中元素的个数
应用场景
1.消息队列: redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端是用lupsh从列表左侧插入元素, 多个消费者客户端使用brpop命令阻塞时的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性
2.文章列表:每个用户都有属于自己的文章列表,现在需要分页展示文章列表,此时可以考虑使用列表,列表不但有序同时支持按照索引范围获取元素。
- 最新列表:list类型的lpush命令和lrange命令能实现最新列表的功能,每次通过lpush命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表,如朋友圈的点赞列表、评论列表
Set集合数据类型
Redis的Set是string类型的无序集合,且不允许重复的成员。它是通过HashTable实现的。具备以下特性:
1、添加、删除,查找的复杂度都是O(1)
2、为集合提供了求交集、并集、差集等操作
常用命令
1 SADD key member1 [member2] 向集合添加一个或多个成员
2 SCARD key 获取集合的成员数
3 SDIFF key1 [key2] 返回给定所有集合的差集
4 SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中
5 SINTER key1 [key2] 返回给定所有集合的交集
6 SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中
7 SISMEMBER key member 判断 member 元素是否是集合 key 的成员
8 SMEMBERS key 返回集合中的所有成员
9 SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合
10 SPOP key 移除并返回集合中的一个随机元素
11 SRANDMEMBER key [count] 返回集合中一个或多个随机数
12 SREM key member1 [member2] 移除集合中一个或多个成员
13 SUNION key1 [key2] 返回所有给定集合的并集
14 SUNIONSTORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中
15 SSCAN key cursor [MATCH pattern] [COUNT count] 迭代集合中的元素
应用场景
好友/关注/粉丝/感兴趣的人集合
随机展示
标签(tag):set集合 类型比较典型的使用场景。
共同好友推荐功能:根据tag求交集,大于某个阈值就可以推荐。
利用唯一性,统计访问网站的所有独立ip
黑名单/白名单:经常有业务出于安全性方面的考虑,需要设置用户黑名单、ip黑名单、设备黑名单等,set类型适合存储这些黑名单数据,sismember命令可用于判断用户、ip、设备是否处于黑名单之中.
Zset sorted set 有序集合数据类型
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。
redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
常用命令
1. ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
2 ZCARD key 获取有序集合的成员数
3 ZCOUNT key min max 计算在有序集合中指定区间分数的成员数
4 ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment
5 ZINTERSTORE destination numkeys key [key ...] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
6 ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量
7 ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合指定区间内的成员
8 ZRANGEBYLEX key min max [LIMIT offset count] 通过字典区间返回有序集合的成员
9 ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员
10 ZRANK key member 返回有序集合中指定成员的索引
11 ZREM key member [member ...] 移除有序集合中的一个或多个成员
12 ZREMRANGEBYLEX key min max 移除有序集合中给定的字典区间的所有成员
13 ZREMRANGEBYRANK key start stop 移除有序集合中给定的排名区间的所有成员
14 ZREMRANGEBYSCORE key min max 移除有序集合中给定的分数区间的所有成员
15 ZREVRANGE key start stop [WITHSCORES] 返回有序集中指定区间内的成员,通过索引,分数从高到低
16 ZREVRANGEBYSCORE key max min [WITHSCORES] 返回有序集中指定分数区间内的成员,分数从高到低排序
17 ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
18 ZSCORE key member 返回有序集中,成员的分数值
19 ZUNIONSTORE destination numkeys key [key ...] 计算给定的一个或多个有序集的并集,并存储在新的 key 中
20 ZSCAN key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成员和元素分值)
应用场景
- 排行榜:有序集合经典使用场景,例如B站需要对用户上传的视频做排行榜,榜单维护可能是多方面: 按照时间、按照播放量、按照获得的点赞投币评论数量等等。
2、带权重的消息队列。
3、滑动窗口限流:可以使用zset实现, score设置为当前时间,每次请求的时候,删除掉过期的窗口,判断数量是否超出了限额。
听完我在那手舞足蹈地吧唧一堆,梦梦酱显露出一脸惊讶地感叹道:
我原本以为自己对Redis基本的数据类型还是知道点的,比如在我们项目中,最常用的是用String类型来做缓存,提供数据的访问性能。没想到,其他的数据类型还有这么多的应用场景啊。
索大心中窃窃暗喜,幸好我之前系统的学习和实战了一下这些知识,答道:
确实是这样的,一般在公司的项目大多数都是那Redis 当做 缓存中间件。但是,谁让人家Redis 做得这么好,支持丰富的数据类型,也能给我们一些不常见需求场景提供解决方案啊。
Redis 不光提供基本的数据类型,还提供一些高级的数据类型,比如:GEO 地理空间数据类型、BitMaps位图数据类型、HyperLogLog基数统计和布隆过滤器、Stream 消息队列等等。
梦梦酱:
Redis还支持这么多的数据类型啊?等你做完一组俯卧撑之后,要不你再给我讲讲呗。
索大:
可以啊,既然梦梦酱那么好学,虽然我自己也了解不是特别深刻,但是我们可以相互探讨一番。
后记
大家好,我是索大,一个认真学习、运动和爱好动漫的技术人,非常感谢大家的支持,同时也感谢我的女朋友梦梦酱给予这些建议和鼓励,我会在公众号【Java绿色通道】分享的知识/技术/运动/日常,希望能和各位一起成长,共同进步。