有序集合类型

在集合类型的基础上有序集合类型为集合中的每个元素都关联了一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能够获得分数最高(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作。虽然集合中每个元素都是不同的,但是它们的分数却可以相同。

有序集合类型在某些方面和列表类型有些相似。二者都是有序的。二者都可以获得某一范围的元素。但是二者有着很大的区别,这使得它们的应用场景也是不同的。

  • 列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会较慢,所以它更加适合实现如“新鲜事”或“日志”这样很少访问中间元素的应用。
  • 有序集合类型是使用散列表和跳跃表(Skip list)实现的,所以即使读取位于中间部分的数据速度也很快(时间复杂度是O(log(N)))。
  • 列表中不能简单地调整某个元素的位置,但是有序集合可以(通过更改这个元素的分数)。
  • 有序集合要比列表类型更耗费内存。

有序集合类型算得上是 Redis的5种数据类型中最高级的类型了,可以与列表类型和集合类型对照理解。

增加元素

ZADD key score member [score member …]

ZADD命令用来向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。ZADD命令的返回值是新加入到集合中的元素个数(不包含之前已经存在的元素)。

假设我们用有序集合模拟计分板,现在要记录Tom、 Peter和David三名运动员的分数(分别是89分、 67分和100分):

redis> ZADD scoreboard 89 Tom 67 Peter 100 David
(integer) 3
#这时我们发现Peter的分数录入有误,实际的分数应该是76分,可以用ZADD命令修改Peter的分数:
redis> ZADD scoreboard 76 Peter
(integer) 0
#分数不仅可以是整数,还支持双精度浮点数:
redis> ZADD testboard 17E+307 a
(integer) 1
redis> ZADD testboard 1.5 b
(integer) 1
redis> ZADD testboard +inf c
(integer) 1
redis> ZADD testboard -inf d
(integer) 1

其中+inf和-inf分别表示正无穷和负无穷。

获得元素的分数

ZSCORE key member

示例如下:

redis> ZSCORE scoreboard Tom
"89"

获得排名在某个范围的元素列表

ZRANGE key start stop [WITHSCORES]

ZREVRANGE key start stop [WITHSCORES]

ZRANGE命令会按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。

ZRANGE命令与LRANGE命令十分相似,如索引都是从0开始,负数代表从后向前查找(-1表示最后一个元素)。就像这样:

redis> ZRANGE scoreboard 0 2
1) "Peter"
2) "Tom"
3) "David"
redis> ZRANGE scoreboard 1 -1
1) "Tom"
2) "David"

如果需要同时获得元素的分数的话可以在ZRANGE命令的尾部加上WITHSCORES参数,这时返回的数据格式就从“元素1, 元素2, …, 元素n”变为了“元素1, 分数1, 元素2, 分数2, …, 元素n, 分数n”,例如:

redis> ZRANGE scoreboard 0 -1 WITHSCORES
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "David"
6) "100"

ZRANGE命令的时间复杂度为0(logn+m)(其中n为有序集合的基数, m为返回的元素个数)。

如果两个元素的分数相同, Redis会按照字典顺序(即"0"< "9"< "A"< "Z"< "a"< "z"这样的顺序)来进行排列。再进一步,如果元素的值是中文怎么处理呢?答案是取决于中文的编码方式,如使用UTF-8编码:

redis> ZADD chineseName 0 马华 0 刘墉 0 司马光 0 赵哲
(integer) 4
redis> ZRANGE chineseName 0 -1
1) "\xe5\x88\x98\xe5\xa2\x89"
2) "\xe5\x8f\xb8\xe9\xa9\xac\xe5\x85\x89"
3) "\xe8\xb5\xb5\xe5\x93\xb2"
4) "\xe9\xa9\xac\xe5\x8d\x8e"

可见此时Redis依然按照字典顺序排列这些元素。

ZREVRANGE命令和ZRANGE的唯一不同在于ZREVRANGE命令是按照元素分数从大到小的顺序给出结果的。

获得指定分数范围的元素

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

ZRANGEBYSCORE命令参数虽然多,但是都很好理解。该命令按照元素分数从小到大的顺序返回分数在min和max之间(包含min和max)的元素:

redis> ZRANGEBYSCORE scoreboard 80 100
1) "Tom"
2) "David"

如果希望分数范围不包含端点值,可以在分数前加上“(”符号。例如,希望返回80分到100分的数据,可以含80分,但不包含100分,则稍微修改一下上面的命令即可:

redis>ZRANGEBYSCORE scoreboard 80 (100
1) "Tom"

min和max还支持无穷大,同ZADD命令一样, -inf和+inf分别表示负无穷和正无穷。比如你希望得到所有分数高于80分(不包含80分)的人的名单,但你却不知道最高分是多少(虽然有些背离现实,但是为了叙述方便,这里假设可以获得的分数是无上限的),这时就可以用上+inf了:

redis> ZRANGEBYSCORE scoreboard (80 +inf
1) "Tom"
2) "David"

WITHSCORES参数的用法与ZRANGE命令一样,不再赘述。

了解SQL语句的读者对LIMIT offset count应该很熟悉,在本命令中 LIMIToffset count与SQL中的用法基本相同,即在获得的元素列表的基础上向后偏移offset个元素,并且只获取前count个元素。为了便于演示,我们先向scoreboard键中再增加些元素:

redis> ZADD scoreboard 56 Jerry 92 Wendy 67 Yvonne
(integer) 3
现在scoreboard键中的所有元素为:
redis> ZRANGE scoreboard 0 -1 WITHSCORES
1) "Jerry"
2) "56"
3) "Yvonne"
4) "67"
5) "Peter"
6) "76"
7) "Tom"
8) "89"
9) "Wendy"
10) "92"
11) "David"
12) "100"

想获得分数高于60分的从第二个人开始的3个人:

redis> ZRANGEBYSCORE scoreboard 60 +inf LIMIT 1 3
1) "Peter"
2) "Tom"
3) "Wendy"

那么,如果想获取分数低于或等于100分的前3个人怎么办呢?

这时可以借助ZREVRANGEBYSCORE命令实现。

需要注意的是ZREVRANGEBYSCORE命令不仅是按照元素分数从大往小的顺序给出结果的,而且它的min和max参数的顺序和ZRANGEBYSCORE命令是相反的。就像这样:

redis> ZREVRANGEBYSCORE scoreboard 100 0 LIMIT 0 3
1) "David"
2) "Wendy"
3) "Tom"

增加某个元素的分数

ZINCRBY key increment member

ZINCRBY命令可以增加一个元素的分数,返回值是更改后的分数。例如,想给Jerry加4分:

redis> ZINCRBY scoreboard 4 Jerry
"60"

increment也可以是个负数表示减分,例如,给Jerry减4分:

redis> ZINCRBY scoreboard -4 Jerry
" 56"

如果指定的元素不存在, Redis在执行命令前会先建立它并将它的分数赋为0再执行操作。

redis数据类型-有序集合的更多相关文章

  1. [PHP] PHP多个进程配合redis的有序集合实现大文件去重

    1.对一个大文件比如我的文件为 -rw-r--r--  1 ubuntu ubuntu  9.1G Mar  1 17:53 2018-12-awk-uniq.txt 2.使用split命令切割成10 ...

  2. php使用redis的有序集合zset实现延迟队列

    延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息. 延迟队列的应用场景: 1.新用户注册,10分钟后发送邮件或站内信. 2.用户下单后,30分钟未支付,订单自动作废. 我 ...

  3. Redis 操作有序集合数据

    Redis 操作有序集合数据: > zadd names "Tom" // zadd 用于往有序集合中添加元素,其中 1 在 Redis 中称为 score(分数),用来进行 ...

  4. python 操作redis之——有序集合(sorted set) (七)

    #coding:utf8 import redis r =redis.Redis(host=") 1.Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中.如果某个成员已经是有序 ...

  5. 【Redis学习之六】Redis数据类型:集合和有序集合

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 redis-2.8.18 一.集合 Set无序的.去重的元素 ...

  6. 9、Redis五大数据类型---有序集合Zset(sorted set)

    一.简介 zset与set异同 相同之处: 都是没有重复元素的字符串集合 不同之处: 有序集合zset的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排 ...

  7. 面试官:Redis中有序集合的内部实现方式是什么?

    面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:有序集合的内部实 ...

  8. redis的有序集合ZSET(stored set)

    相关命令 1.ZADD ZADD key-name score member [score member……] 将带有给定分值的成员添加到有序集合里 2.ZREM ZREM  key-name mem ...

  9. Redis之有序集合命令

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

随机推荐

  1. Zabbix实战-简易教程(4)--Server端安装

    在数据库安装完成后,接着开始安装server端了.我们这里采用yum安装. 3.2.0 安装需求 ● PHP 5.6.18 ● curl 7.47.1 ● zabbix_server (Zabbix) ...

  2. Spring+SpringMVC+MyBatis+easyUI整合优化篇

    优化篇 Spring+SpringMVC+MyBatis+easyUI整合优化篇(一)System.out.print与Log Spring+SpringMVC+MyBatis+easyUI整合优化篇 ...

  3. Jquery_基础(三) ajax与json

    什么是ajax? AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. ...

  4. 爬虫、请求库selenium

    阅读目录 一 介绍 二 安装 三 基本使用 四 选择器 五 等待元素被加载 六 元素交互操作 七 其他 八 项目练习 一 介绍 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决r ...

  5. Redux入门示例-TodoList

    Tip 前端技术真是日新月异,搞完 React 不搭配个数据流都不好意思了.满怀期待的心去翻了翻 flux,简直被官方那意识流的文档折服了,真是又臭又长还是我智商问题?

  6. C语言中%d,%p,%u,%lu等都有什么用处

    %d 有符号10进制整数(%ld 长整型,%hd短整型 )%hu 无符号短整形(%u无符号整形,%lu无符号长整形)%i 有符号10进制整数 (%i 和%d 没有区别,%i 是老式写法,都是整型格式) ...

  7. 关于win10系统安装VMware12Pro后,win10系统的 控制面板\网络和 Internet\网络连接\更改适配器选项卡中 没有虚拟网卡VMnet1和VMnet8图标,该如何把他们显示出来呢?

    安装VMware12Pro后,PC主机通过命令行:ipconfig/all ,查看发现没有VMnet1和VMnet8. 然后我首先尝试打开VMware12Pro的虚拟网络编辑器: 然后先点击" ...

  8. c++(单词统计)

    在面试环节中,有一道题目也是考官们中意的一道题目:如果统计一段由字符和和空格组成的字符串中有多少个单词? 其实,之所以问这个题目,考官的目的就是想了解一下你对状态机了解多少. (1) 题目分析 从题目 ...

  9. NYOJ 1248 海岛争霸(Dijkstra变形——最短路径最大权值)

    题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=1248 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比 ...

  10. 教你搭建你自己的Git服务器

    http://lib.csdn.net/article/git/50086 导读 现在我们将要学习如何搭建 git 服务器,如何编写自定义的 Git 钩子来在特定的事件触发相应的动作(例如通知),或者 ...