zoukankan      html  css  js  c++  java
  • redis 在 php 中的应用(Sorted-set篇)

    本文为我阅读了 redis参考手册 之后编写,注意 php_redis 和 redis-cli 的区别(主要是返回值类型和参数用法)

    Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

    不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

    有序集合的成员是唯一的,但分数(score)却可以重复。

    集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 

    目录:

    Sorted-set(有序集合)
    ZADD ZREM ZCARD ZCOUNT ZSCORE ZINCRBY
    ZRANGE ZREVRANGE ZRANGEBYSCORE ZREVRANGEBYSCORE ZREMRANGEBYSCORE ZINTER
    ZUNION ZRANK  ZREVRANK   ZREMRANGEBYRANK    

    Sorted-set(有序集合)

    1、ZADD

    Redis Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。(分数值可以是整数值或双精度浮点数。)

    (1)如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。

    (2)如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。

    (3)当 key 存在但不是有序集类型时,返回一个错误。

    注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。

    语法:

    redis 127.0.0.1:6379> ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN

    返回值: 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。

    可用版本:>= 1.2.0

    时间复杂度:O(M*log(N)),N是有序集的基数,M为成功添加的新成员的数量。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    
    var_dump($redis -> zRange('myset',0,-1,'withScores'));
    //array (size=5)
    //  'hello' => float 0
    //  'foo' => float 1
    //  'world' => float 1
    //  'hi' => float 2
    //  'welcome' => float 2.5
    
    $redis -> zAdd('myset',3,'hi');     // hi 已经是 myset 的成员,此时更新分数值并重新插入这个成员元素
    var_dump($redis -> zRange('myset',0,-1,'withScores'));
    //array (size=5)
    //  'hello' => float 0
    //  'foo' => float 1
    //  'world' => float 1
    //  'welcome' => float 2.5
    //  'hi' => float 3
    复制代码

    2、ZREM

    Redis Zrem 命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略

    当 key 存在但不是有序集类型时,返回一个错误。

    注意: 在 Redis 2.4 版本以前, ZREM 每次只能删除一个元素。

    语法:

    redis 127.0.0.1:6379> ZREM key member

    返回值: 被成功移除的成员的数量,不包括被忽略的成员。

    可用版本:>= 1.2.0

    时间复杂度:O(M*log(N)),N为有序集的基数,M为被成功移除的成员的数量。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    
    $redis ->zRem('myset','hi');          // 一处集合中的某个元素
    var_dump($redis -> zRange('myset',0,-1,'withScores'));
    //array (size=4)
    //  'hello' => float 0
    //  'foo' => float 1
    //  'world' => float 1
    //  'welcome' => float 2.5
    复制代码

    3、ZCARD

    Redis Zcard 命令用于计算集合中元素的数量。

    语法:

    redis 127.0.0.1:6379> ZCARD KEY_NAME

    返回值: 当 key 存在且是有序集类型时,返回有序集的基数。 当 key 不存在时,返回 0 。

    可用版本:>= 1.2.0

    时间复杂度:O(1)

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    
    var_dump($redis ->zCard('myset'));          // int 5
    复制代码

    4、ZCOUNT

    Redis Zcount 命令用于计算有序集合中指定分数区间的成员数量。

    语法:

    redis 127.0.0.1:6379> ZCOUNT key min max

    返回值: 分数值在 min 和 max 之间的成员的数量。

    可用版本:>= 2.0.0

    时间复杂度:O(log(N)+M),N为有序集的基数,M为值在minmax之间的元素的数量。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    // 1分到3分之间的值有5个
    var_dump($redis ->zCount('myset',1,3));          // int 5
    复制代码

    5、ZSCORE

    Redis Zscore 命令返回有序集中,成员的分数值。 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 nil 。

    语法:

    redis 127.0.0.1:6379> ZSCORE key member

    返回值: 成员的分数值,以字符串形式表示。

    可用版本:>= 1.2.0

    时间复杂度:O(1)

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    // 返回 foo 的分数值
    var_dump($redis ->zScore('myset','foo'));          // float 1
    复制代码

    6、ZINCRBY

    Redis Zincrby 命令对有序集合中指定成员的分数加上增量 increment(分数值可以是整数值或双精度浮点数。)

    (1)可以通过传递一个负数值 increment ,让分数减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。

    (2)当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。

    (3)当 key 不是有序集类型时,返回一个错误。

    语法:

    redis 127.0.0.1:6379> ZINCRBY key increment member

    返回值: member 成员的新分数值,以字符串形式表示。

    可用版本:>= 1.2.0

    时间复杂度:O(log(N))具体实例:

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    // 将 world 的分数增加0.6
    var_dump($redis ->zIncrBy('myset',0.6,'world'));          // float 1.6
    
    // 将 score 的分减去1.2
    var_dump($redis ->zIncrBy('myset',-1.2,'score'));          // float 1.8
    复制代码

    7、ZRANGE

    Redis Zrange 返回有序集中,指定区间内的成员。(其中成员的位置按分数值递增(从小到大)来排序。具有相同分数值的成员按字典序(lexicographical order )来排列。)

    如果你需要成员按值递减(从大到小)来排列,请使用 ZREVRANGE 命令。

    下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。

    你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。

    语法:

    redis 127.0.0.1:6379> ZRANGE key start stop [WITHSCORES]

    返回值:指定区间内,带有分数值(可选)的有序集成员的列表。

    可用版本:>= 1.2.0

    时间复杂度:O(log(N)+M),N为有序集的基数,而M为结果集的基数。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    var_dump($redis ->zRange('myset',0,-1,'withScore'));
    //array (size=6)
    //  'hello' => float 0
    //  'foo' => float 1
    //  'world' => float 1
    //  'hi' => float 2
    //  'welcome' => float 2.5
    //  'score' => float 3
    复制代码

    8、ZREVRANGE

    Redis Zrevrange 命令返回有序集中,指定区间内的成员

    其中成员的位置按分数值递减(从大到小)来排列。

    具有相同分数值的成员按字典序的逆序(reverse lexicographical order)排列。

    除了成员按分数值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。

    语法:

    redis 127.0.0.1:6379> ZREVRANGE key start stop [WITHSCORES]

    返回值:指定区间内,带有分数值(可选)的有序集成员的列表。

    可用版本:>= 1.2.0

    时间复杂度:O(log(N)+M),N为有序集的基数,而M为结果集的基数

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');      //  集合中的元素唯一,但是分数可以重复
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    var_dump($redis ->zRevRange('myset',0,-1,'withScore'));
    //array (size=6)
    //  'score' => float 3
    //  'welcome' => float 2.5
    //  'hi' => float 2
    //  'world' => float 1
    //  'foo' => float 1
    //  'hello' => float 0
    复制代码

    9、ZRANGEBYSCORE

    Redis Zremrangebyscore 命令用于移除有序集中,指定分数(score)区间内的所有成员。

    语法:

    redis 127.0.0.1:6379> ZREMRANGEBYSCORE key min max

    返回值:被移除成员的数量。

    可用版本:>= 1.2.0

    时间复杂度:O(log(N)+M),N为有序集的基数,M为被结果集的基数。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    var_dump($redis ->zRangeByScore('myset',2,3));
    //array (size=3)
    //  0 => string 'hi' (length=2)
    //  1 => string 'welcome' (length=7)
    //  2 => string 'score' (length=5)
    
    var_dump($redis ->zRangeByScore('myset','-inf','+inf'));    // 返回分数值从负无穷到正无穷之间的值
    //array (size=6)
    //  0 => string 'hello' (length=5)
    //  1 => string 'foo' (length=3)
    //  2 => string 'world' (length=5)
    //  3 => string 'hi' (length=2)
    //  4 => string 'welcome' (length=7)
    //  5 => string 'score' (length=5)
    
    var_dump($redis -> zRange('myset',0,-1,'withScore'));       // 原集合不变
    //array (size=6)
    //  'hello' => float 0
    //  'foo' => float 1
    //  'world' => float 1
    //  'hi' => float 2
    //  'welcome' => float 2.5
    //  'score' => float 3
    复制代码

    10、ZREVRANGEBYSCORE

    Redis Zrevrangebyscore 返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列。

    具有相同分数值的成员按字典序的逆序(reverse lexicographical order )排列。

    除了成员按分数值递减的次序排列这一点外, ZREVRANGEBYSCORE 命令的其他方面和 ZRANGEBYSCORE 命令一样。

    语法:

    redis 127.0.0.1:6379> ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

    返回值:指定区间内,带有分数值(可选)的有序集成员的列表。

    可用版本:>= 2.2.0

    时间复杂度:O(log(N)+M),N为有序集的基数,M为结果集的基数。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    var_dump($redis ->zRevRangeByScore('myset',3,2));
    //array (size=3)
    //  0 => string 'score' (length=5)
    //  1 => string 'welcome' (length=7)
    //  2 => string 'hi' (length=2)
    
    var_dump($redis ->zRevRangeByScore('myset','+inf','-inf'));    // 返回分数值从正无穷到负无穷之间的值
    //array (size=6)
    //  0 => string 'score' (length=5)
    //  1 => string 'welcome' (length=7)
    //  2 => string 'hi' (length=2)
    //  3 => string 'world' (length=5)
    //  4 => string 'foo' (length=3)
    //  5 => string 'hello' (length=5)
    
    var_dump($redis -> zRange('myset',0,-1,'withScore'));       // 原集合不变
    //array (size=6)
    //  'hello' => float 0
    //  'foo' => float 1
    //  'world' => float 1
    //  'hi' => float 2
    //  'welcome' => float 2.5
    //  'score' => float 3
    复制代码

    11、ZREMRANGEBYSCORE

    Redis Zremrangebyscore 命令用于移除有序集中指定分数(score)区间内的所有成员。

    语法:

    redis 127.0.0.1:6379> ZREMRANGEBYSCORE key min max

    返回值:被移除成员的数量。

    可用版本:>= 1.2.0

    时间复杂度:O(log(N)+M),N为有序集的基数,而M为被移除成员的数量。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');      // score=0
    $redis -> zAdd('myset',1,'world');      // score=2
    $redis -> zAdd('myset',1,'foo');        // score=1
    $redis -> zAdd('myset',2,'hi');         // score=2
    $redis -> zAdd('myset',2.5,'welcome');  // score=2.5
    $redis -> zAdd('myset',3,'score');      // score=3
    
    var_dump($redis ->zRemRangeByScore('myset',1,3));    // int 5
    
    var_dump($redis ->zRange('myset',0,-1,'withScore'));
    //array (size=1)
    //  'hello' => float 0
    复制代码

    12、ZINTER

    Redis Zinter 命令计算给定的一个或多个有序集的交集. (作用与 redis 在 cmd 命令下的 ZINTERSTORE 作用相同)

    默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和

    语法:

    redis 127.0.0.1:6379> ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

    返回值:保存到目标结果集的的成员数量。

    可用版本:>= 2.0.0

    时间复杂度:O(N*K)+O(M*log(M)),N为给定key中基数最小的有序集,K为给定有序集的数量,M为结果集的基数。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');      // score=0
    $redis -> zAdd('myset',1,'world');      // score=2
    $redis -> zAdd('myset',1,'foo');        // score=1
    $redis -> zAdd('myset',2,'hi');         // score=2
    $redis -> zAdd('myset',2.5,'welcome');  // score=2.5
    $redis -> zAdd('myset',3,'score');      // score=3
    
    $redis -> zAdd('otherset',0,'good');
    $redis -> zAdd('otherset',1,'hello');
    $redis -> zAdd('otherset',2,'world');
    
    $array_set = array('myset','otherset');
    var_dump($redis ->zInter('destinationset',$array_set));    // int 2
    var_dump($redis ->zRange('destinationset',0,-1,'withScore'));
    //array (size=2)
    //  'hello' => float 1
    //  'world' => float 3
    复制代码

    13、ZUNION

    Redis Zunionstore 命令计算给定的一个或多个有序集的并集.(其作用与 redis 在 cmd 中ZUNIONSTORE 相同)

    默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和 。

    语法:

    redis 127.0.0.1:6379> ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

    返回值:保存到 destination 的结果集的成员数量。

    可用版本:>= 2.0.0

    时间复杂度:O(N)+O(M log(M)),N为给定有序集基数的总和,M为结果集的基数。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');      // score=0
    $redis -> zAdd('myset',1,'world');      // score=2
    $redis -> zAdd('myset',1,'foo');        // score=1
    $redis -> zAdd('myset',2,'hi');         // score=2
    $redis -> zAdd('myset',2.5,'welcome');  // score=2.5
    $redis -> zAdd('myset',3,'score');      // score=3
    
    $redis -> zAdd('otherset',0,'good');    // score=0
    $redis -> zAdd('otherset',1,'hello');   // score=1
    $redis -> zAdd('otherset',2,'world');   // score=2
    
    $array_set = array('myset','otherset');
    var_dump($redis ->zUnion('destinationset',$array_set));    // int 7
    var_dump($redis ->zRange('destinationset',0,-1,'withScore'));
    //array (size=7)
    //  'good' => float 0
    //  'foo' => float 1
    //  'hello' => float 1
    //  'hi' => float 2
    //  'welcome' => float 2.5
    //  'score' => float 3
    //  'world' => float 3
    复制代码

    14、ZRANK

    Redis Zrank 返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。

    语法:

    redis 127.0.0.1:6379> ZRANK key member

    返回值:如果成员是有序集 key 的成员,返回 member 的排名。 如果成员不是有序集 key 的成员,返回 nil 。

    可用版本:>= 2.0.0

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

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    var_dump($redis ->zRank('myset','welcome'));    // int 4
    复制代码

    15、ZREVRANK

    Redis Zrevrank 命令返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。

    排名以 0 为底,也就是说, 分数值最大的成员排名为 0 。

    语法:

    redis 127.0.0.1:6379> ZREVRANK key member

    返回值:如果成员是有序集 key 的成员,返回成员的排名。 如果成员不是有序集 key 的成员,返回 nil 。

    可用版本:>= 2.2.0

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

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');
    $redis -> zAdd('myset',1,'world');
    $redis -> zAdd('myset',1,'foo');
    $redis -> zAdd('myset',2,'hi');
    $redis -> zAdd('myset',2.5,'welcome');
    $redis -> zAdd('myset',3,'score');
    
    var_dump($redis ->zRevRank('myset','welcome'));    // int 1
    复制代码

    16、ZREMRANGEBYRANK

    Redis Zremrangebyrank 命令用于移除有序集中指定排名(rank)区间内的所有成员

    语法:

    redis 127.0.0.1:6379> ZREMRANGEBYRANK key start stop

    返回值:被移除成员的数量。

    可用版本:>= 2.0.0

    时间复杂度:O(log(N)+M),N为有序集的基数,而M为被移除成员的数量。

    具体实例:

    复制代码
    <?php
    $redis = new redis();
    $redis -> connect('127.0.0.1',6379);
    $redis -> flushAll();
    
    $redis -> zAdd('myset',0,'hello');      // rank=0
    $redis -> zAdd('myset',1,'world');      // rank=2
    $redis -> zAdd('myset',1,'foo');        // rank=1
    $redis -> zAdd('myset',2,'hi');         // rank=3
    $redis -> zAdd('myset',2.5,'welcome');  // rank=4
    $redis -> zAdd('myset',3,'score');      // rank=5
    
    var_dump($redis ->zRemRangeByRank('myset',1,3));    // int 3
    
    var_dump($redis ->zRange('myset',0,-1,'withScore'));
    //array (size=3)
    //  'hello' => float 0
    //  'welcome' => float 2.5
    //  'score' => float 3
    复制代码

     如有转载,请注明出处http://www.cnblogs.com/chrdai/p/6851731.html

  • 相关阅读:
    Oracle函数如何把符串装换为小写的格式
    Oralce中的synonym同义词
    JS中getYear()的兼容问题
    How to do SSH Tunneling (Port Forwarding)
    所谓深度链接(Deep linking)
    upload size of asp.net
    发一个自动刷网站PV流量的小工具
    解决Visual Studio 2008 下,打开.dbml(LINQ) 文件时,提示"The operation could not be completed." 的问题。
    在资源管理器中使鼠标右键增加一个命令,运行cmd,同时使得当前路径为资源管理器当前的目录
    使用SQL语句获取Sql Server数据库的版本
  • 原文地址:https://www.cnblogs.com/dreamboycx/p/10776222.html
Copyright © 2011-2022 走看看