前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Redis入门到精通四】Redis核心数据类型(Sorted set,Stream,Bitmap,Bitfield,Geospatial,Hyperloglog)

【Redis入门到精通四】Redis核心数据类型(Sorted set,Stream,Bitmap,Bitfield,Geospatial,Hyperloglog)

作者头像
小皮侠
发布2024-09-24 19:18:39
1260
发布2024-09-24 19:18:39
举报
文章被收录于专栏:Java学习从基础到就业

Redis

前两篇文章中我已经对Redis中String,Hash,List,Set从内部编码到命令进行了详细展开和介绍,本篇文章将会对剩下的核心数据类型进行介绍,其中常见的Sorted set我会进行详细介绍,剩余的数据类型不会对操作命令进行展开介绍,有需要的友友们可以自行查阅Redis官方文档,上面有详细的使用教程。

1.Sorted set类型

有序集合保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数(score)与之关联,着使得有序集合中的元素是可以维护有序性的,但这个有序不是⽤下标作为排序依据⽽是⽤这个分数。有序集合提供了获取指定分数和元素范围查找、计算成员排名等功能可以方便我们解决很多开发中遇到的问题。需要注意的是,有序集合中元素不能重复但是分数是可以重复的,分数相同按照key的字典表排序

(1)常见命令

操作Sorted Set类型的常用命令有:zadd,zcard,zscore,zrank,zrevrank,zrem,zincrby,zrange,zrevrange,zrangebyscore,zrevrangebyscore,zcount,zremrangebyrank,zremrangebyscore,zinterstore,zunionstore。下面将按顺序依次介绍用法。

代码语言:javascript
复制
ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]

时间复杂度O(log(N)),zadd用于添加或者更新指定的元素以及关联的分数到 zset 中,分数应该符合 double 类型,+inf/-inf 作为正负极限也是合法的。

  • XX:仅仅⽤于更新已经存在的元素,不会添加新元素。
  • NX:仅⽤于添加新元素,不会更新已经存在的元素。
  • CH:默认情况下,ZADD 返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更新的元素的个数。
  • INCR:此时命令类似 ZINCRBY 的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数。
代码语言:javascript
复制
ZCARD key

时间复杂度O(1),zcard用于获取zset中元素的个数。

代码语言:javascript
复制
ZCOUNT key min max

时间复杂度O(log(N)), zcount用于返回分数在min和max之间的元素个数,默认情况下,min和max都是包含的,可以通过左括号(排除。即zcount key (1 (3将结果的区间从左闭右闭改为左开右开。

代码语言:javascript
复制
ZRANGE key start stop [WITHSCORES]

时间复杂度O(log(N)+M), zrange用于返回指定区间里的元素,分数按照升序。带上withscores可以把分数也返回。

代码语言:javascript
复制
ZREVRANGE key start stop [WITHSCORES]

时间复杂度O(log(N)+M),zrevrange用于返回指定区间里的元素,分数按照降序。带上withscores可以把分数也返回。

代码语言:javascript
复制
ZRANGEBYSCORE key min max [WITHSCORES]

时间复杂度O(log(N)+M),zrangebyscore用于返回分数在min和max之间的元素,默认情况下,min和max都是包含的,可以通过左括号(排除。

代码语言:javascript
复制
ZPOPMAX key [count]

时间复杂度O(log(N)*M),zpop用于删除并返回分数最高的count个元素。

代码语言:javascript
复制
BZPOPMAX key [key ...] timeout

时间复杂度O(log(N)),bzpopmax为zpopmax的阻塞版本,什么是阻塞版本可以见我之前对List类型中的blpop和brpop的介绍。

代码语言:javascript
复制
ZPOPMIN key [count]

时间复杂度O(log(N)*M),zpopmin用于删除并返回分数最低的count个元素。

代码语言:javascript
复制
BZPOPMIN key [key ...] timeout

时间复杂度O(log(N)),bzpopmin为zpopmin的阻塞版本。

代码语言:javascript
复制
ZRANK key member

时间复杂度O(log(N)),zrank用于返回在升序状态下指定元素的排名。

代码语言:javascript
复制
ZREVRANK key member

时间复杂度O(log(N)),zrevrank用于返回在降序状态下指定元素的排名。

代码语言:javascript
复制
ZSCORE key member

时间复杂度O(1),zscore用于返回指定元素的分数。

代码语言:javascript
复制
ZREM key member [member ...]

时间复杂度O(M*log(N)),zrem用于删除指定的元素。

代码语言:javascript
复制
ZREMRANGEBYRANK key start stop

时间复杂度O(log(N)+M),zremrangebyrank按照升序删除指定返回内的元素,左闭右闭。

代码语言:javascript
复制
ZREMRANGEBYSCORE key min max

时间复杂度O(log(N)+M),zremrangebyscore按照分数删除指定范围的元素,左闭右闭。

代码语言:javascript
复制
ZINCRBY key increment member

时间复杂度O(log(N)),zincrby用于为指定的元素的关联分数添加指定的分数值。

代码语言:javascript
复制
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

时间复杂度O(N*K)+O(M*log(M)),N 是输⼊的有序集合中, 最⼩的有序集合的元素个数; K 是输⼊了⼏个有序集合; M 是最终结果的有序集合的元素个数。

zinterstore用于求出给定有序集合中元素的交集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。

代码语言:javascript
复制
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

时间复杂度O(N)+O(M*log(M)) ,N 是输⼊的有序集合总的元素个数; M 是最终结果的有序集合的元素个数。

zunionstore用于求出给定有序集合中元素的并集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。

(2)内部编码

有序集合类型在内存中存储时的内部编码方式有ziplist,skiplist两种方式。Redis会根据当前值的类型和长度动态决定使用哪种内部编码实现,可以通过object encoding key 命令来查看编码方式。

  • ziplist(压缩列表):当有序集合的元素个数⼩于 zset-max-ziplist-entries 配置(默认 128 个),同时每个元素的值都⼩于 zset-max-ziplist-value 配置(默认 64 字节)时,Redis 会⽤ ziplist 来作为有序集合的内部实现,ziplist 可以有效减少内存的使⽤。
  • skiplist(跳表):当 ziplist 条件不满⾜时,有序集合会使⽤ skiplist 作为内部实现,因为此时 ziplist 的操作效率会下降。

2.其他核心数据类型

redis给我们提供的数据类型最为广泛使用的是以上五种,但是redis还为我们提供了以下几种数据类型以便于我们在特定场景下使用,下面我们就依据官方文档来具体了解下下面的类型分别都是干什么的。

(1)Stream

Stream可以用来监听客户端,类似于事件传播机制,倘若客户端有某些改变,遍会向stream中添加某些元素并通知消费者。

redis中的stream本质上就是一个队列(阻塞队列),是redis作为一个消息队列的重要支撑。

(2)Geospatial

geospatial 是一种存储坐标(经纬度)的数据结构,它存储一些点之后,就可以让用户给定一个坐标,去从刚才存储的点里进行查找(按照半径或者矩形区域)。在地图类软件中用处广泛。

(3)Bitmap

bitmaps即位图,使用比特位来存储元素,例如存储10,只需要把第十个比特位的0改为一就可以表示把10存起来了,查找的时候只需要判断第n位元素是0或者1就可以表示n这个元素存不存在。

位图的本质上还是一个集合,属于是Set类型针对整数的特定优化版本,大量节省了空间,并且操作高效。

(4)Bitfield

bitfields即位域, 是一种让我们精确进行位操作的一种方法,和C语言中的位段十分相似。bitfield可以理解为一串二进制序列(字节数组),同时可以把这个字节数组中的某几个位赋予特定的含义,并且可以进行读取/修改/算术运算 相关操作。

下面是C语言中的位段

代码语言:javascript
复制
struct Test{
int a:8;
int b:16;
int c:8;//此处的数字就描述了这个成员实际占几个bit位
}

即把一个结构体所占空间的前八个比特位定义为a,中间16个比特位定义为16,后边八个比特位定义为c,以此来精确进行位操作。

(5)Hyperloglog

从官方文档可以看到,hyperloglog是一种概率性数据结构, 用最高不超过12kb的空间来统计集合中的基数(不重复的元素个数),且错误率保持在百分之0.81以内。假设我们有一万亿个数据,里面有重复的有不重复的,现在我们想找到这万亿个数据中有多少种数(即多少个不重复的元素),就可以使用hyperloglog。

hyperloglog的算法原理是根据抛硬币的概率逆推而来,我们假设同时抛20枚硬币,要让这20枚硬币的正面全部朝上,极大的概率我们需要抛2的20次方次,同样的在计算机中我们生成一个随机数,倘若这个随机数的最后20位为20个连续的0的概率依旧是2的20次方。我们可以使用特殊的加密算法把一个万亿级别的数据存储在计算机中,相同的元素会转化为相同的随机数,不同的元素加密之后也不可能相同,我们把这万亿级别的数据依次进行转化,然后记录最后比特位连续n位为零的最大数max,我们便可以认为2的max次方即这万亿个数据的基数。这样的算法只需要O(N)的时间复杂度,因为我们不需要比较,且空间上只需要万亿个比特位的空间,这是非常少的。我们可以用这个算法快速的计算出一个极大数据的基数,但这并不是准确的。

例如:我们用来统计王者荣耀服务器的UV(用户访问次数),假设用Set来统计,用Set来存储userId,每个userId按照8个字节来算,一亿的用户就需要8亿字节的内存也就是0.8G,但是使用hyperloglog只需要不到12kb便可以实现。

❤️😍😍😍😍😍😍😍😍😍😍😍😍😍😍😍😍😍 🍔我是小皮侠,谢谢大家都能看到这里!! 🦚主页已更新Java基础内容,数据结构基础,数据库,算法 🚕未来会更新Java项目,SpringBoot,Redis以及各种Java路线会用到的技术。 🎃求点赞!求收藏!求评论!求关注! 🤷‍♀️谢谢大家!!!!!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Redis
    • 1.Sorted set类型
      • (1)常见命令
      • (2)内部编码
    • 2.其他核心数据类型
      • (1)Stream
      • (2)Geospatial
      • (3)Bitmap
      • (4)Bitfield
      • (5)Hyperloglog
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档