redis的学习(三)

6. set集合

集合:把一些有关联的数据放在一起。

1、集合中的元素是无序的,即数据存放顺序不重要,变化一下顺序,集合依旧是之前的集合。

2、集合中的元素是不能重复的(唯一性)与list类似的是集合中的每一个元素也都是string类型的,可以使用json格式的字符串存储结构化数据。

6.1 set指令

SADD : 将⼀个或者多个元素添加到set中,重复的元素⽆法添加到set中。

SADD key member [member ...]

时间复杂度:O(1)

返回值:本次添加成功的元素个数。

SMEMBERS 获取⼀个set中的所有元素,元素间的顺序是⽆序的。

SMEMBERS key

时间复杂度:O(N)

返回值:所有元素的列表。

SISMEMBER :判断⼀个元素在不在set中。

SISMEMBER key member

时间复杂度:O(1)

返回值:1表⽰元素在set中。0表⽰元素不在set中或者key不存在。

spop:随机删除一个或多个元素。

SPOP key [count]

时间复杂度:O(N),n是count

返回值:取出的元素。

SMOVE 将⼀个元素从源set取出并放⼊⽬标set中。

SMOVE source destination member

时间复杂度:O(1)

返回值:1表⽰移动成功,0表⽰失败。

srem:将指定的元素从set中删除。

SREM key member [member ...]

时间复杂度:O(N),N是要删除的元素个数.

返回值:本次操作删除的元素个数。

6.2 集合间的操作

交集(inter)、并集(union)、差集(diff)的概念如图所⽰。

SINTER:给定set的交集中的元素。

SINTER key [key ...]

时间复杂度:O(N*M),N是最⼩的集合元素个数.M是最⼤的集合元素个数.

返回值:交集的元素。

SINTERSTORE 获取给定set的交集中的元素并保存到⽬标set中。

SINTERSTORE destination key [key ...]

时间复杂度:O(N*M),N是最⼩的集合元素个数.M是最⼤的集合元素个数.

返回值:交集的元素个数。

SUNION 获取给定set的并集中的元素。

SUNION key [key ...]

时间复杂度:O(N),N给定的所有集合的总的元素个数.

返回值:并集的元素。

SUNIONSTORE 获取给定set的并集中的元素并保存到⽬标set中。

SUNIONSTORE destination key [key ...]

时间复杂度:O(N),N给定的所有集合的总的元素个数.

返回值:并集的元素个数。

SDIFF 获取给定set的差集中的元素。

SDIFF key [key ...]

时间复杂度:O(N),N给定的所有集合的总的元素个数.

返回值:差集的元素。

SDIFFSTORE 获取给定set的差集中的元素并保存到⽬标set中。

SDIFFSTORE destination key [key ...]

时间复杂度:O(N),N给定的所有集合的总的元素个数.

返回值:差集的元素个数。

6.3 内部编码

java中的set本质上是一个接口,其实现方式可以是treeset或hashset。

intset(整数集合):为了节省空间做的特定优化。当元素为整数,且元素的个数不是很多的时候。

hashtable(哈希表):当集合类型⽆法满⾜intset的条件时,Redis会使⽤hashtable作为集合 的内部实现。

6.4 set的应用场景

1、使用set来保存用户的标签

2、方便计算交集

3、使用set统计uv:

1、pv page view 用户每一次访问浏览器,都会产生一个pv。

2、uv user view 用户每一次访问浏览器,都会产生一个uv。但是同一个用户多次访问同一个页面只会增加一次uv。

7.zset 有序集合

zset排序的规则:给zset中的member引入一个属性分数(score,浮点类型),每一个member都会安排一个分数,进行排序的时候,就是按照次数的分数的大小进行升序或降序排的。zset中的member要求是唯一的,但是其score不是唯一的。

7.1 列表、集合、有序集合三者的异同点

7.2 操作指令

ZADD:添加或者更新指定的元素以及关联的分数到zset中,分数应该符合double类型,+inf/-inf作为正负 极限也是合法的。可以根据member来查找score,也可以通过score查找member。

ZADD的相关选项:

• XX:仅仅⽤于更新已经存在的元素,不会添加新元素。元素指的是member。

• NX:仅⽤于添加新元素,不会更新已经存在的元素。

• CH:默认情况下,ZADD返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次修改的元素的个数。

• INCR:此时命令类似ZINCRBY的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和 分数。

lt:less than 现在更新分数,给定的值要比之前的值分数小,就进行更新,负责不更新。

gt:greater than:只有分数数值大于之前的数值的时候才会进行更新。

ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]

时间复杂度:O(log(N)),n是有序集合中已经存在的元素个数。由于zset是有序结构,在新增元素的时候要进行找位置。

返回值:本次添加成功的元素个数。

如果两个member的score是一样的话,就按照元素自身的字典序来排列。zset内部实际是按照升序排列的。

zrange:查看有序集合中的元素详情了,redis内部存储数据的时候,是按照二进制的方式来存储的,即redis服务器不负责"字符编码",要把二进制字节转回到汉字,就需要在客户端进行指令"redis-cli --raw"

查询带分数的值:zrange key 0 -1 withscores

ZRANGE :返回指定区间⾥的元素,分数按照升序。带上WITHSCORES可以把分数也返回。

ZRANGE key start stop [WITHSCORES] 处的[start, stop] 为下标构成的区间.从0开始,⽀持负数. 时间复杂度:O(log(N)+M),表示两个区间之间的元素的个数。

返回值:区间内的元素列表

ZCARD:获取⼀个zset的基数(cardinality),即zset中的元素个数。

ZCARD key

时间复杂度:O(1)

返回值:zset内的元素个数

ZCOUNT 返回分数在min和max之间的元素个数,默认情况下,min和max都是包含的,可以通过(排除。

ZCOUNT key min max

时间复杂度:O(log(N)),zset内部会记录每一个元素当前的排行,直接查询max和min元素,就知道了这两个元素的次序,然后做减法获取返回值。

返回值:满⾜条件的元素列表个数。

排除min值的语法:ZCOUNT key (min max,加一个括号。

排除max的语法:ZCOUNT key min (max,也加一个括号。

min和max可以写成浮点数,inf.表示无穷大,- inf.表示无穷大。

ZREVRANGE :返回指定区间⾥的元素,分数按照降序。带上WITHSCORES可以把分数也返回。

ZREVRANGE key start stop [WITHSCORES]

时间复杂度:O(log(N)+M)

返回值:区间内的元素列表。

语法中的-1,表示len-1.

ZRANGEBYSCORE:返回分数在min和max之间的元素,默认情况下,min和max都是包含的,可以通过(排除。

ZRANGEBYSCORE key min max [WITHSCORES]

时间复杂度:O(log(N)+M)

返回值:区间内的元素列表。

ZPOPMAX 删除并返回分数最⾼的count个元素。

ZPOPMAX key [count]

时间复杂度:O(log(N)*M)

返回值:分数和元素列表。

BZPOPMAX :ZPOPMAX的阻塞版本。每一个key都是一个有序集合。阻塞也是在有序集合为空的时候触发的阻塞,阻塞到有其他客户端插入元素。

BZPOPMAX key [key ...] timeout

时间复杂度:O(log(N))

返回值:元素列表。

当然如果有序集合中已经有了元素,就直接返回元素,不用进行阻塞了。如果当前bzpopmax同时监听了多个key,假设有m个key,此时的时间复杂度依旧是O(log(N))。

ZPOPMIN :删除并返回分数最低的count个元素。

ZPOPMIN key [count]

时间复杂度:O(log(N)*M)

返回值:分数和元素列表。

虽然redis的有序函数记录了开头的元素,但是删除的时候使用的是通用的删除函数,故此导致了重新查找的过程。

BZPOPMIN :ZPOPMIN的阻塞版本。

BZPOPMIN key [key ...] timeout

时间复杂度:O(log(N))

返回值:元素列表。

ZRANK :返回指定元素的排名(下标),升序的方式。

ZRANK key member

时间复杂度:O(log(N))

返回值:排名。

ZREVRANK :返回指定元素的排名,降序的方式。

ZREVRANK key member

时间复杂度:O(log(N))

返回值:排名。

ZSCORE 返回指定元素的分数。

ZSCORE key member

时间复杂度:O(1)

返回值:分数

此处相当于redis对于这样的查询操作做了特殊的优化,通过扩大空间的消耗面对与时间复杂度优化到了o(1)。

ZREM 删除指定的元素。

ZREM key member [member ...]

时间复杂度:O(M*log(N)),m是参数的个数

返回值:本次操作删除的元素个数。

ZREMRANGEBYRANK 按照排序,升序删除指定范围的元素,左闭右闭。

ZREMRANGEBYRANK key start stop

时间复杂度:O(log(N)+M)

返回值:本次操作删除的元素个数。

ZREMRANGEBYSCORE 按照分数删除指定范围的元素,左闭右闭。

ZREMRANGEBYSCORE key min max

时间复杂度:O(log(N)+M)

返回值:本次操作删除的元素个数。

ZINCRBY 为指定的元素的关联分数添加指定的分数值。

ZINCRBY key increment member

时间复杂度:O(log(N))

返回值:增加后元素的分数。

zinterstore:交集,结果保存到另一个key中。

zunionstore:并集,结果保存到另一个key中。

所谓权重就是每一个部分占整体的分量的比例。

aggregate:统计,合计。

在zset中,member才是元素本体,score只是辅助排序的工具人,因此在进行比较"相同"的时候,只要member相同即可,score不一样无所谓。但是求交集的时候相同元素不同score的最终score应该怎样计算。

计算规则按照aggregate的sum,max,min这三种方式进行计算。默认是sum的方式。

时间复杂度:o(n*k)+o(m*log(n)),n是输入若干个有序集合,里面元素最小的个数。k是吧k个有序集合求交集,m是最终结果的有序集合元素个数。近似来算可以看成

o(m*log(m))。

ZUNIONSTORE: 求并集

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <sum | max | min> ]

时间复杂度:O(N)+O(M*log(M)) N是输⼊的有序集合总的元素个数;M是最终结果的有序集合的元素 个数. 返回值:⽬标集合中的元素个数

7.3 内部编码

1、当元素个数较少且每个元素较⼩时,内部编码为ziplist:

2、当元素个数较多或者单个元素体积较大,内部编码skiplist:

7.4 zset的应用场景

1、排行榜系统

1m字节是百万级别,1g是十亿字节级别。

8. streams

事件:每次socket上都有可读可写的数据,都会通过事件回调机制来通知相关的应用程序代码。有些操作不知道啥时候出现,所以只能等事情出现之后再采取动作。

streams类似于一个阻塞队列。属于是list的blpop/brpop的升级版本。

9. geospatial

地理空间。用来存储坐标,存储一些点之后,根据用户给定的一个坐标和半径扫描,去查找redis中存储的符合条件的位置坐标。一般应用于地图中查找位置和定点范围内地点查询。

10. hyperloglog

应用场景只有一个,估算集合中的元素的个数。

使用set记录浏览器的uv,可以知道每一个uv的相关详细信息。但是需要消耗很大的空间资源。hyperloglog最多使用12kb的空间实现对于上亿次uv的数量统计,但是仅仅是统计数量,并不能知道每一个uv的访问信息。

但是该指令存在0.81%的估算误差。

11. bitmaps

位图:使用bit位来表示整数。本质上还是一个集合,属于是set类型针对整数的特化版本。bitmap相对于hyplerloglog,能够存储元素。

下面将10存储到位图中:

12. bitfields

位域,本质上是让我们进行精确进行位操作的一种方法。bitfields可以理解成一串二进制序列(字节数组),同时可以把这个字节数组的某几个位赋予特定的含义,进行一系列的相关操作。该效果相对于string和hash也是节省了大部分空间。

ps:谢谢观看!

相关推荐
Felix_12157 小时前
2025 西电软工数据结构机考 Tip (By Felix)
算法
飞yu流星8 小时前
C++ 函数 模板
开发语言·c++·算法
没有名字的鬼8 小时前
C_字符数组存储汉字字符串及其索引
c语言·开发语言·数据结构
pursuit_csdn8 小时前
力扣 74. 搜索二维矩阵
算法·leetcode·矩阵
labuladuo5208 小时前
洛谷 P8703 [蓝桥杯 2019 国 B] 最优包含(dp)
算法·蓝桥杯·动态规划
Milk夜雨9 小时前
C语言冒泡排序教程简介
数据结构·算法·排序算法
一直学习永不止步9 小时前
LeetCode题练习与总结:随机翻转矩阵--519
java·数学·算法·leetcode·哈希表·水塘抽样·随机化
xiao--xin9 小时前
LeetCode100之组合总和(39)--Java
java·开发语言·算法·leetcode·回溯
IT猿手11 小时前
部落竞争与成员合作算法(CTCM)求解5个无人机协同路径规划(可以自定义无人机数量及起始点),MATLAB代码
深度学习·算法·机器学习·matlab·无人机·无人机、