Redis zet 和 set 求差集

本文介绍了一种利用Redis的ZUNIONSTORE命令实现差集查询的方法。通过设置特定的权重,使得并集中的差集部分的score变为0,进而通过查询score为0的元素来获取差集。这一技巧不仅适用于简单的集合操作,也为更复杂的数据统计提供了灵活的解决方案。

这里是用了求并集的命令来求差集,是一个比较好的统计手段。

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

这个 demo 是求了两个集合的并集:

sadd allusers donkey cat chipmonk trashpanda
zadd didusers 1 donkey 1 trashpanda
zunionstore didntdo 2 didusers allusers weights 1 0
zrangebyscore didntdo 0 0
1) "cat"
2) "chipmonk"

第三行的命令
ZUNIONSTORE destination numSets zset1 set2 weights weight1 weight2

参数:

  • numkeys:参与求交集的集合的数量
  • weight*:这里有两个 weight, 分别是求交集的时候每个元素的 score 的乘数因子,若是 set 没有score,便默认其 score 为 1;

这里的 weight2 = 0,于是并集中差集部分的 score 便是 0,只需列出 score 为 0 的 便是差集了:
zrangebyscore didntdo 0 0.

Redis中list、setzset在多个方面存在区别: ### 数据特性 - **list**:是一个有序的字符串列表,可在列表两端进行元素的插入删除操作,元素可以重复。例如,使用`lpush``rpush`命令可分别从列表左侧右侧插入元素。 ```python # 示例命令 import redis r = redis.Redis() r.lpush('mylist', 'element1') r.rpush('mylist', 'element2') ``` - **set**:是无序的、唯一的字符串合,自动去重。添加重复元素时,合不会有任何变化。 ```python # 示例命令 r.sadd('myset', 'element1') r.sadd('myset', 'element1') # 重复元素,合不会改变 ``` - **zset**:是有序合,每个元素关联一个分数(score),根据分数对元素进行排序,元素也是唯一的。 ```python # 示例命令 r.zadd('myzset', {'element1': 1, 'element2': 2}) ``` ### 内部编码 - **list**:在Redis 6中,list的内部编码可以是`ziplist`或`linkedlist`,而Redis 7中是`listpack``linkedlist`。`ziplist`(Redis 7中的`listpack`)适用于元素较少且元素长度较短的情况,节省内存;`linkedlist`适用于元素较多的情况。 - **set**:当合中的元素都是整数并且元素个数小于`set-max-intset-entries`配置(默认512个)时,Redis会选用`intset`来作为合的内部实现,以减少内存的使用;否则使用`hashtable` [^3]。 ```python # 示例命令 r.sadd('myset', 1, 2, 3) # 可能使用intset编码 ``` - **zset**:在Redis 6中,zset有`ziplist``skiptable`两种编码格式,Redis 7是`listpack``skiptable`。当元素个数不超过`zset-max-ziplist-entries`(默认128)且单个元素大小不超过`zset-max-ziplist-value`(默认64byte)时,使用`ziplist`(Redis 7中的`listpack`);否则使用`skiptable` [^1][^4]。 ### 应用场景 - **list**:常用于消息队列、任务队列等场景,利用其可以在两端进行操作的特性实现先进先出(FIFO)或后进先出(LIFO)的队列。 - **set**:适用于去重、交、并、差等操作的场景,如共同好友、推荐系统等。 ```python # 示例命令 r.sadd('set1', 'a', 'b', 'c') r.sadd('set2', 'b', 'c', 'd') common_friends = r.sinter('set1', 'set2') # 求交 ``` - **zset**:适合需要根据某个分数进行排序的场景,如排行榜、热门列表等。 ```python # 示例命令 r.zadd('leaderboard', {'user1': 100, 'user2': 200}) top_users = r.zrevrange('leaderboard', 0, 1) # 获取前两名用户 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值