一. 有序集合概述

  Redis 有序集合对象和集合对象一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。

  在前面第9章中讲到Redis 数据对象对应不同底层的数据结构,对于有序集合对象 编码可以是ziplist 或者skiplist二种。skiplist编码的底层数据结构可以参考"redis 系列7 数据结构之跳跃表"。ziplist编码的压缩列表结构以后再讲。

  1.1  ziplist编码

    ziplist编码的有序集合对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member),而第二个元素则保存元素的分值(score)。压缩列表的集合元素按分值从小到大进行排序,分值较小的元素被放置在靠近表头的方向,分值较大的元素则被放置在靠近表尾的方向。

    下例中,使用zadd命令,创建一个有序集合对象作为price键的值。并且该对象使用的编码是ziplist。

    127.0.0.1:> zadd price 8.5 apple 5.0 banana
(integer)
127.0.0.1:> object encoding price
"ziplist"

  1.2   skiplist编码

    skiplist编码的有序集合对象使用字典和跳跃表作为底层实现,如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员是比较长的字符串时,Redis就会使用跳跃表来作为有序集合键的底层实现。

    下例中,还是使用zadd命令,创建一个有序集合对象作为store键的值。并且该对象使用的编码是skiplist。

    127.0.0.1:> zadd store 1.0
"long_long_long_long_long_long_long_long_long_long_long_long..." -- 省去了字符,大于64字节
127.0.0.1:> object encoding store
"skiplist"

  1.3 编码的转换

    当有序集合可以同时满足以下两个条件时,对象使用ziplist编码:

      (1) 有序集合保存的元素数量小于128个。

      (2) 有序集合的所有元素成员的长度都小于64字节。

    127.0.0.1:> config get zset-max-ziplist-value
) "zset-max-ziplist-value"
) ""
127.0.0.1:> config get zset-max-ziplist-entries
) "zset-max-ziplist-entries"
) ""

  

二. 有序集合对象命令实现

-- Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。返回被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
127.0.0.1:> zadd price 8.5 apple 5.0 banana
(integer) -- Zcard 命令用于计算集合中元素的数量。
127.0.0.1:> zcard price
(integer) -- Zcount 命令用于计算有序集合中指定分数区间的成员数量
127.0.0.1:> zrange price - withscores
) "banana"
) ""
) "pear"
) ""
) "apple"
) "8.5"
127.0.0.1:> zcount price 5.0 7.0 -- 取scores值范围
(integer) -- Zincrby 命令对有序集合中指定成员的分数加上增量 increment, 可以通过传递一个负数值 increment ,让分数减去相应的值。
127.0.0.1:> zrange price - withscores
) "pear"
) ""
127.0.0.1:> zincrby price 2.5 pear -- 添加2.5元
"8.5" -- Zinterstore 命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。结果集中分数值是成员分数值之和。
127.0.0.1:> ZADD mid_test "Li Lei" --第一个key mid_test
(integer)
127.0.0.1:> ZADD mid_test "Han Meimei"
(integer)
127.0.0.1:> ZADD fin_test "Li Lei" -- 第二个key fin_test
(integer)
127.0.0.1:> ZADD fin_test "Han Meimei"
(integer)
127.0.0.1:> zinterstore sum_point mid_test fin_test -- sum_point是destination,2是二个key
(integer)
127.0.0.1:> zrange sum_point - withscores --分数值之和
) "Han Meimei"
) ""
) "Li Lei"
) "" --Zlexcount 命令在计算有序集合中指定字典区间内成员数量.
127.0.0.1:> zadd myzset a b c d e f g
(integer)
127.0.0.1:> zlexcount myzset [c [g --获取c 到g 的区间数量
(integer) -- Zrange 返回有序集中,指定区间内的成员,其中成员的位置按分数值递增(从小到大)来排序。
127.0.0.1:> zrange price - withscores
) "banana"
) ""
) "pear"
) ""
) "apple"
) "8.5" -- Zrangebylex 通过字典区间返回有序集合的成员。
127.0.0.1:> zadd myzset a b c d e f g
(integer)
127.0.0.1:> zrangebylex myzset [c [g
) "c"
) "d"
) "e"
) "f"
) "g" -- Zrangebyscore 返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。更多用法见官方文档
127.0.0.1:> ZADD salary jack
(integer)
127.0.0.1:> ZADD salary tom
(integer)
127.0.0.1:> ZADD salary peter
(integer)
127.0.0.1:> zrangebyscore salary withscores --返回工资范围
) "jack"
) ""
) "tom"
) ""
127.0.0.1:> ZRANGEBYSCORE salary -inf WITHSCORES --返回工资小于5000范围
) "jack"
) ""
) "tom"
) "" --Zrank 返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。下面是jack 分值排名0位, peter分值排名2位。
127.0.0.1:> zrank salary jack
(integer) --
127.0.0.1:> zrank salary peter
(integer) --
-- Zrem 命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略。
127.0.0.1:> ZRANGE salary - WITHSCORES
) "jack"
) ""
) "tom"
) ""
) "peter"
) ""
127.0.0.1:> zrem salary jack --移除jack成员成功
(integer) --Zremrangebylex 命令用于移除有序集合中给定的字典区间的所有成员。
127.0.0.1:> zrange myzset -
) "a"
) "b"
) "c"
) "d"
) "e"
) "f"
) "g"
127.0.0.1:> zremrangebylex myzset [a [c --移除了a到c的成员数据
(integer) --Zremrangebyrank 命令用于移除有序集中,指定排名(rank)区间内的所有成员.
127.0.0.1:> zrange salary -
) "tom"
) "peter"
127.0.0.1:> zremrangebyrank salary --移除了分值排名为0的成员
(integer) --称除了tom 成员分值排0, peter分值排1
127.0.0.1:> zrange salary -
) "peter" -- Zremrangebyscore 命令用于移除有序集中,指定分数(score)区间内的所有成员。
127.0.0.1:> zrange salary -
) "peter"
127.0.0.1:> zremrangebyscore salary --移除分值的范围,peter分值为12000
(integer) --Zrevrange 命令返回有序集中,指定区间内的成员,分数值 (从大到小)来排列. 与zrange命令一样,分值排列相反。
127.0.0.1:> zrevrange salary - withscores
) "peter"
) ""
) "tom"
) ""
) "jack"
) "" -- Zrevrangebyscore 返回有序集中指定分数区间内的所有的成员。有序集成员按分数值 (从大到小)的次序排列。
127.0.0.1:> zrevrangebyscore salary withscores --返回分值范围
) "tom"
) ""
) "jack"
) "" -- Zrevrank 命令返回有序集中成员的排名。其中有序集成员按分数值(从大到小)排序
127.0.0.1:> zrevrank salary tom
(integer) --tom工资排名第二
127.0.0.1:> zrevrank salary peter
(integer) --peter工资排名第一 -- Zscore 命令返回有序集中,成员的分数值。
127.0.0.1:> zscore salary peter
"" --Zunionstore 命令计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。
127.0.0.1:> zrange salary - withscores --第一个key
) "jack"
) ""
) "tom"
) ""
) "peter"
) ""
127.0.0.1:> zrange salary2 - withscores --第二个key
) "tom"
) ""
) "jack"
) ""
127.0.0.1:> zunionstore salaries salary salary2 --合并到salaries的key中
(integer)
127.0.0.1:> zrange salaries - withscores
) "jack"
) ""
) "tom"
) ""
) "peter"
) ""

    

redis 系列14 有序集合对象的更多相关文章

  1. 《闲扯Redis十一》Redis 有序集合对象底层实现

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...

  2. 从Redis中删除大集合对象的方法

    Redis中的大集合对象,如set.zset等,如果有上千万个元素,一般是不能直接用del命令来删除的,因为del命令可能会耗时几秒钟,而redis本身是单线程的,在高并发的情况下会阻塞大量的请求,严 ...

  3. 第二百九十九节,python操作redis缓存-SortSet有序集合类型,可以理解为有序列表

    python操作redis缓存-SortSet有序集合类型,可以理解为有序列表 有序集合,在集合的基础上,为每元素排序:元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值, ...

  4. redis系列-14点的灵异事件

    概述 项目组每天14点都会遭遇惊魂时刻.一条条告警短信把工程师从午后小憩中拉回现实.之后问题又神秘消失.是PM喊你上工了?还是服务器给你开玩笑?下面请看工程师如何一步一步揪出真凶,解决问题. 如果不想 ...

  5. redis:order set有序集合类型的操作(有序集合)

    1. order set有序集合类型的操作(有序集合) 有序集合是在无序集合的基础上加了一个排序的依据,这个排序依据叫score,因此声明一个集合为有序集合的时候要加上score(作为排序的依据) 1 ...

  6. Redis学习---Redis操作之有序集合

    有序集合,在集合的基础上,为每元素排序:元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序. zadd(name, *args, **kw ...

  7. redis:php-redis中有序集合 zset的使用

    ZSET(stored set) 和 set 一样是字符串的集合,不同的是每个元素都会关联一个 double 类型的 score .实现使用的是 skip list 和 hash table , sk ...

  8. redis列表和有序集合

    redis中的list数据类型是可以插入重复数据的,有去重的需求的话可以用redis有序集合数据类型 Redis Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中. 如果某个成员已经是 ...

  9. redis 入门之有序集合

    zadd 将一个或多个 member 元素及其 score 值加入到有序集 key 当中.如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 ...

随机推荐

  1. tomcat运行后提示Could not create the Java Virtual Machine.

    大致的问题是Java虚拟机(JVM)分配的内存大于系统可用内存,一开始去网上找了些资料,大多是都是说修改MyEclipse安装目录下的elicpse.ini文件中的内存大小.但我试了之后发现然并软,后 ...

  2. vue样式控制的方式

    创建vue对象: 1.样式控制第一种方式: 直接传递一个数组,注意: 这里的 class 需要使用  v-bind 做数据绑定. 2.样式控制第二种方式: 在数组中使用三元表达式 3.样式控制第三种方 ...

  3. 车道线识别之 tusimple 数据集介绍

    Tusimple 是一家做自动驾驶的公司,他也公布了一些其在自动驾驶领域积累的数据,其中有一些是和车道线检测相关的.2018年6 月份,其举办了一次以摄像头图像数据做车道检测的比赛,公开了一部分数据及 ...

  4. 谈谈Java的classpath

    Java之ClassPath 大家刚开始写Java代码的时候,如果使用Eclipse作为IDE,同时需要引用其他的类库,一般会有如下操作 在工程中新建lib目录 将jar包复制到lib目录下 右键单击 ...

  5. [POJ1193][NOI1999]内存分配(链表+模拟)

    题意 时 刻 T 内存占用情况 进程事件 0 1 2 3 4 5 6 7 8 9 进程A申请空间(M=3, P=10)<成功> 1 A 2 A B 进程B申请空间(M=4, P=3)< ...

  6. Jenkins pipeline job 根据参数动态获取触发事件的分支

    此文需要有Jenkins pipeline job 的简单使用经验 场景 我们日常的测试函数, 一般是不能仅仅在本地跑的,还需要一个公共的跑测试的环境,作为合并新的PR的依据. 如果用Jenkins ...

  7. netcore应用程序部署程序到ubuntu

    运维需求:获取服务器的运行情况,是否CPU.内存较高等,上报到运维系统 环境:ubuntu16.04 工具::netcore2.1.supervisor 程序实现(代码就不贴了)参考:https:// ...

  8. firewalld的基本使用

    参考原文链接:https://www.cnblogs.com/moxiaoan/p/5683743.html 1.firewalld的基本使用 启动: systemctl start firewall ...

  9. MUI消息推送

    一.push通过H5+实现 简单实现方式:通过轮询服务器是否有新消息推送过来 mui.plusReady(function() { plus.navigator.closeSplashscreen() ...

  10. Redis_MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk问题解决

    原因:可参考https://www.linuxidc.com/Linux/2012-07/66079.htm 解决方案一: 修改redis.conf中 stop-writes-on-bgsave-er ...