Redis对象——有序集合(ZSet)
有序集合类型 (Sorted Set或ZSet) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序值。有序集合保留了集合不能有重复成员的特性(分值可以重复),但不同的是,有序集合中的元素可以排序。
一、内部实现
有序集合是由 ziplist (压缩列表) 或 skiplist (跳跃表) 组成的。
当数据比较少时,有序集合使用的是 ziplist 存储的,有序集合使用 ziplist 格式存储必须满足以下两个条件:
- 有序集合保存的元素个数要小于 128 个;
- 有序集合保存的所有元素成员的长度都必须小于 64 字节。
如果不能满足以上两个条件中的任意一个,有序集合将会使用 skiplist 结构进行存储。
有关ziplist 和skiplist 这两种redis底层数据结构的具体实现可以参考我的另外两篇文章。
二、常用命令
Redis列表对象常用命令如下表(点击命令可查看命令详细说明)。
命令 | 说明 | 时间复杂度 |
---|---|---|
BZPOPMAX key [key ...] timeout | 从一个或多个排序集中删除并返回得分最高的成员,或阻塞,直到其中一个可用为止 | O(log(N)) |
BZPOPMIN key [key ...] timeout | 从一个或多个排序集中删除并返回得分最低的成员,或阻塞,直到其中一个可用为止 | O(log(N)) |
ZADD key [NXXX] [CH] [INCR] score member [score member ...] | 添加到有序set的一个或多个成员,或更新的分数,如果它已经存在 | O(log(N)) |
ZCARD key | 获取一个排序的集合中的成员数量 | O(1) |
ZCOUNT key min max | 返回分数范围内的成员数量 | O(log(N)) |
ZINCRBY key increment member | 增量的一名成员在排序设置的评分 | O(log(N)) |
ZINTERSTORE | 相交多个排序集,导致排序的设置存储在一个新的关键 | O(NK)+O(Mlog(M)) |
ZLEXCOUNT key min max | 返回成员之间的成员数量 | O(log(N)) |
ZPOPMAX key [count] | 删除并返回排序集中得分最高的成员 | O(log(N)*M) |
ZPOPMIN key [count] | 删除并返回排序集中得分最低的成员 | O(log(N)*M) |
ZRANGE key start stop [WITHSCORES] | 根据指定的index返回,返回sorted set的成员列表 | O(log(N)+M) |
ZRANGEBYLEX key min max [LIMIT offset count] | 返回指定成员区间内的成员,按字典正序排列, 分数必须相同。 | O(log(N)+M) |
ZREVRANGEBYLEX key max min [LIMIT offset count] | 返回指定成员区间内的成员,按字典倒序排列, 分数必须相同 | O(log(N)+M) |
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] | 返回有序集合中指定分数区间内的成员,分数由低到高排序。 | O(log(N)+M) |
ZRANK key member | 确定在排序集合成员的索引 | O(log(N)) |
ZREM key member [member ...] | 从排序的集合中删除一个或多个成员 | O(M*log(N)) |
ZREMRANGEBYLEX key min max | 删除名称按字典由低到高排序成员之间所有成员。 | O(log(N)+M) |
ZREMRANGEBYRANK key start stop | 在排序设置的所有成员在给定的索引中删除 | O(log(N)+M) |
ZREMRANGEBYSCORE key min max | 删除一个排序的设置在给定的分数所有成员 | O(log(N)+M) |
ZREVRANGE key start stop [WITHSCORES] | 在排序的设置返回的成员范围,通过索引,下令从分数高到低 | O(log(N)+M) |
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] | 返回有序集合中指定分数区间内的成员,分数由高到低排序。 | O(log(N)+M) |
ZREVRANK key member | 确定指数在排序集的成员,下令从分数高到低 | O(log(N)) |
ZSCORE key member | 获取成员在排序设置相关的比分 | O(1) |
ZUNIONSTORE | 添加多个排序集和导致排序的设置存储在一个新的关键 | O(N)+O(M log(M)) |
ZSCAN key cursor [MATCH pattern] [COUNT count] | 迭代sorted sets里面的元素 | O(1) |
三、使用场景
3.1 排行榜系统
有序集合比较典型的使用场景就是排行榜系统。例如学生成绩的排名。某视频(博客等)网站的用户点赞、播放排名、电商系统中商品的销量排名等。我们以博客点赞为例。
- 添加用户赞数
例如小编Tom发表了一篇博文,并且获得了10个赞。
zadd user:ranking arcticle1 10
- 取消用户赞数
这个时候有一个读者又觉得Tom写的不好,又取消了赞,此时需要将文章的赞数从榜单中减去1,可以使用zincrby。
zincrby user:ranking arcticle1 -1
- 查看某篇文章的赞数
ZSCORE user:ranking arcticle1
- 展示获取赞数最多的十篇文章
此功能使用zrevrange命令实现:
zrevrangebyrank user:ranking 0 9
3.2 电话号码(姓名)排序
使用有序集合的ZRANGEBYLEX(点击可查看该命令详细说明)或ZREVRANGEBYLEX可以帮助我们实现电话号码或姓名的排序,我们以ZRANGEBYLEX为例
注意:不要在分数不一致的SortSet集合中去使用 ZRANGEBYLEX和 ZREVRANGEBYLEX 指令,因为获取的结果会不准确。
- 电话号码排序
我们可以将电话号码存储到SortSet中,然后根据需要来获取号段:
redis> zadd phone 0 13100111100 0 13110114300 0 13132110901
(integer) 3
redis> zadd phone 0 13200111100 0 13210414300 0 13252110901
(integer) 3
redis> zadd phone 0 13300111100 0 13310414300 0 13352110901
(integer) 3
获取所有号码:
redis> ZRANGEBYLEX phone - +
1) "13100111100"
2) "13110114300"
3) "13132110901"
4) "13200111100"
5) "13210414300"
6) "13252110901"
7) "13300111100"
8) "13310414300"
9) "13352110901"
获取132号段:
redis> ZRANGEBYLEX phone [132 (133
1) "13200111100"
2) "13210414300"
3) "13252110901"
获取132、133号段:
redis> ZRANGEBYLEX phone [132 (134
1) "13200111100"
2) "13210414300"
3) "13252110901"
4) "13300111100"
5) "13310414300"
6) "13352110901"
- 姓名排序
将名称存储到SortSet中:
redis> zadd names 0 Toumas 0 Jake 0 Bluetuo 0 Gaodeng 0 Aimini 0 Aidehua
(integer) 6
获取所有人的名字:
redis> ZRANGEBYLEX names - +
1) "Aidehua"
2) "Aimini"
3) "Bluetuo"
4) "Gaodeng"
5) "Jake"
6) "Toumas"
获取名字中大写字母A开头的所有人:
redis> ZRANGEBYLEX names [A (B
1) "Aidehua"
2) "Aimini"
获取名字中大写字母C到Z的所有人:
redis> ZRANGEBYLEX names [C [Z
1) "Gaodeng"
2) "Jake"
3) "Toumas"
小结
本篇文章我们总结了Redis 有序集合对象的内部实现、常用命令以及常用的一些场景,有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助我们在实际开发中解决很多问题。那么大家在项目中对Redis有序集合对象的使用都有哪些场景呢,欢迎在评论区给我留言和分享,我会第一时间反馈!我们共同学习与进步!
参考
《Redis设计与实现》
《Redis开发与运维》
《Redis官方文档》
-----END-----
Redis对象——有序集合(ZSet)的更多相关文章
- php使用redis的有序集合zset实现延迟队列
延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息. 延迟队列的应用场景: 1.新用户注册,10分钟后发送邮件或站内信. 2.用户下单后,30分钟未支付,订单自动作废. 我 ...
- 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)
redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...
- redis的有序集合ZSET(stored set)
相关命令 1.ZADD ZADD key-name score member [score member……] 将带有给定分值的成员添加到有序集合里 2.ZREM ZREM key-name mem ...
- redis 有序集合(zset)函数
redis 有序集合(zset)函数 zAdd 命令/方法/函数 Adds the specified member with a given score to the sorted set stor ...
- 9、Redis五大数据类型---有序集合Zset(sorted set)
一.简介 zset与set异同 相同之处: 都是没有重复元素的字符串集合 不同之处: 有序集合zset的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排 ...
- [PHP] PHP多个进程配合redis的有序集合实现大文件去重
1.对一个大文件比如我的文件为 -rw-r--r-- 1 ubuntu ubuntu 9.1G Mar 1 17:53 2018-12-awk-uniq.txt 2.使用split命令切割成10 ...
- Redis 操作有序集合数据
Redis 操作有序集合数据: > zadd names "Tom" // zadd 用于往有序集合中添加元素,其中 1 在 Redis 中称为 score(分数),用来进行 ...
- python 操作redis之——有序集合(sorted set) (七)
#coding:utf8 import redis r =redis.Redis(host=") 1.Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中.如果某个成员已经是有序 ...
- redis有序集合-zset
概念:它是在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动按新的值调整顺序.可以理解为有两列的mysql表,一列存储value,一列存储顺序,操作中 ...
随机推荐
- 使用numpy和PIL实现图像的手绘效果
输入 输出 代码如下 图像的手绘效果的实现 from PIL import Image import numpy as np a = np.array(Image.open("index.j ...
- java虚拟机学习记录(内存划分、垃圾回收、类加载等机制)
一直以来觉得虚拟机是Java最难的一部分,涉及最底层的原理,学起来难度很大,而且工作中基本上用不到这些原理,所以对这部分“敬而远之”.现如今工作五年了,从Java基础到算法.数据结构.网络.数据库.设 ...
- 【简说Python WEB】pyechart在flask中的应用
个人笔记总结,可读性不高.只为自己总结用.怕日后忘记. 这里用到了tushare,pandas等python组件. pyechart的案例 c = ( Bar() .add_xaxis([" ...
- 学习笔记----C语言的面向对象
2020-03-26 21:27:17 面向对象的编程语言都有一个类的概念,像Java.python等.类是对特定数据的特定操作的集合体.它包含两个范畴:数据和操作.C语言是没有类的概念的,但是 ...
- HTML中的IE条件注释,让低版本IE也能正常运行HTML5+CSS3网站的3种解决方案
最近的项目中,因为需要兼容IE7,IE8,IE9,解研究了IE的条件注释,顺手写下来备忘. HTML中的IE条件注释 IE条件注释是一种特殊的HTML注释,这种注释只有IE5.0及以上版本才能理解. ...
- git 更换push 提交地址
git 删除远程地址 1.找到对应项目 右键点击 GIT Bash Here 2.输入命令 git remote rm origin 3.对应项目 右键点击 GIT Sync..... 4.点击Man ...
- [A*,启发式搜索] [SCOI2005] 骑士精神
链接:https://ac.nowcoder.com/acm/problem/20247来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- JMeter入门介绍
目录 概述 下载&安装 实战JMetetr 测试计划简述 准备测试计划 编写测试计划 录制测试脚本 执行性能测试 单机测试 分布式测试 分析测试报告 APDEX 响应时间和吞吐量统计 测试结果 ...
- 【译】Java SE 14 Hotspot 虚拟机垃圾回收调优指南
原文链接:HotSpot Virtual Machine Garbage Collection Tuning Guide,基于Java SE 14. 本文主要包括以下内容: 优化目标与策略(Ergon ...
- Java数据结构与排序
一.引子:想要给ArrayList排序却发现没有排序方法?你有两种选择: 1.换用TreeSet: 2.使用Collection.sort(List<T> list) ...