Redis 基础

语法

首先,Redis 是 key - Value 键值对内存数据库,它使用五种基本数据类型来保存 Value 数据,我们先来看看 Redis 中对 Key 的相关操作,后面再来介绍这五种 Value 类型,下面我们分别来介绍。

Redis 的 Key

查找:keys、randomkey、exists、type 和 dump 命令

// keys pattern : pattern 是键的匹配模式,与正则表达式稍有差异
// pattern 允许通配符 ?(匹配一个任意字符),*(匹配任意多个任意字符),若要匹配 ?、* 等特殊字符则使用 \ 进行转义,
// 同时允许使用正则表达式中的 [] ,但不与 ?、* 同用,似也不能使用预编译的 \d ,\S 等
keys [^0-9]*    // 匹配不以数字开头的所有 Key

// randomkey : 从所有的 Key 中随机返回一个

// exists Key :判断指定的 Key 是否存在

// type Key :判断指定的 Key 保存着何种类型的 Value 

// dump Key : 将指定的 Key 序列化后返回

修改:rename 和 renamenx 命令

// rename old_Key new_Key :更改指定 Key(由 old_Key 指定) 的名字为 new_Key
// renamenx old_Key new_Key :更改指定 Key(由 old_Key 指定) 的名字为 new_Key,如果 new_Key 不存在的话。
//                            失败返回 (integer) 0

删除:del 命令

// del Key :删除指定名称的 Key

定时操作:expire、pexpire、expireat、pexpireat、persist、ttl 和 pttl 命令

// expire Key seconds :设置此键 seconds 秒后失效,成功返回 1
// pexpire Key mills :设置此键 mills 毫秒后失效,成功返回 1

// expireat Key timestamp:设置此键在 (Unix) timestamp 这个时间点失效,以秒为单位,成功返回 1
// pexpireat Key timestamp:设置此键在 (Unix) timestamp 这个时间点失效,以毫秒为单位,成功返回 1

// persist Key :设置 Key 不会失效,成功返回 1

// ttl Key  :返回此键距离失效还多长时间,以秒为单位,返回值: -2 无此键盘,-1 无失效,> 0 有效值
// pttl Key :返回此键距离失效还多长时间,以毫秒为单位,返回值: -2 无此键盘,-1 无失效,> 0 有效值

接下来,我们就来了解一下 Redis 的五种 Value 类型。

String 字符串

String 类型就是字符串类型,它是二进制安全的,也就是说字符串是以二进制流进行处理,不会对其进行其余的操作,比方说转义字符,"\\" 在其余环境下可能就是一个 "\" ,但是在 Redis 中它就是 "\\",String 类型的值最多能够存储 512 MB 的数据,接下来我们简单看一下,如何在 Redis 中保存和查找一个字符串值:

保存: set、mset、setex、psetex、setnx 和 msetnx 命令

  // set String_Key String_Value: 设置一个字符串类型的 Redis 键值对
  // setnx String_Key String_Value: 如果指定的键不存在就设置一个字符串类型的 Redis 键值对
  set stringkey stringvalue

  // set 命令一次只能设置一个 Key-Value 对,而 mset 可以同时设置多个 Key-Value 对
  // mset Key_1 Value_1 [Key_2 Value_2] [...]:同时设置多个字符串类型的 Redis 键值对
  // msetnx Key_1 Value_1 [Key_2 Value_2] [...]:同时设置多个字符串类型的 Redis 键值对,但是一旦出现重复全部不生效
  mset key1 value1 key2 value2 key3 value3

  // setex String_Key seconds String_Value :设置 String 类型的 Redis 键值对,但是在 seconds 秒后此键失效
  setex key1 5 value1        // 5 秒后 key1 失效

  // psetex String_Key mills String_Value :设置 String 类型的 Redis 键值对,但是在 mills 毫秒后此键失效
  psetex key2 1000 value2    // 1000 毫秒后 key2 失效

查找: get、getrange、getbit、mget 和 strlen 命令

  // get String_Key :获取指定 Redis 键的字符串值
  get stringkey
  执行结果: "stringvalue"

  // getrange String_Key start end :获取指定 Redis 键的字符串值中指定索引区间 [start, end] 中的字符集合
  getrange stringkey 0 -6
  运行结果:"string"

为什么是 "string" 呢?那是因为 Redis 索引设置的问题,对于一个字符串,它这样规定:

顺序索引:  0    1    2    3    5    6    7    8    9   10   11
逆序索引: -11  -10  -9   -8   -7   -6   -5   -4   -3   -2   -1
字符串值:  s    t    r    i    n    g    v    a    l    u    e

可以看出规定顺序索引是从 0 开始的,而一个负数索引,比如 -6 指的是从右往左(逆序)数过来的第六位字符,所以 [0, -6] 表示从左边第一位开始到逆序数来的第六位为止,这个概念很重要,后面会重复利用到,也会再简单重复一次。

// getbit String_Key offset:获取指定 Redis 键的字符串值的二进制流中偏移开头第一位的二进制位
getbit stringkey 6    // 运行结果:(integer) 1

这个 1 是怎么来的呢?因为 getbit 是获取二进制流中的偏移二进制位,所以我们需要写出 stringkey 对应值 stringvalue 的二进制流,这里因为只偏移 6 ,而 s 的 ascii 码为 115 ,对应二进制编码为 : 01110011,而偏移 6 位就是第 7 位的二进制值,也就是 1,故得 1。

// 同理,get 只能查一个 Redis 键值对,而 mget 可以查多个
// mget  String_Key1 [String_Key2] [...] : 获取多个指定 Redis 键的字符串值
mget key1 key2 key3
执行结果: 1) "value1"
          2) "value2"
          3) "value3"

// strlen String_Key :获取指定 Redis 键的字符串值的长度,也就是由多少个字符组成
strlen stringkey    // 运行结果:(integer) 11

修改:getset、incr、incrby、incrbyfloat、decr、decrby 、append 和 setbit 命令

// getset String_Key String_Value :设置新值并返回旧值
getset stringkey string_value_new    // 运行结果:"stringvalue"

// incr stringkey :将指定 Redis 键的字符串值加一,如果可以的话。返回修改后的值
// decr stringkey :将指定 Redis 键的字符串值减一,如果可以的话。返回修改后的值
setex test 60 1
incr test         // 运行结果:"2"
decr test         // 运行结果:"1"

// incrby / incrbyfloat stringkey increment : 将指定 Redis 键的字符串值加 increment,如果可以的话。
//        前者要为整数字符串,后者为浮点数字符串,返回修改后的值
// decrby stringkey increment : 将指定 Redis 键的字符串值减 increment,如果可以的话。
//        值要为整数字符串,返回修改后的值
setex test 60 1
incr test 3        // 运行结果:(integer) 4
decr test 3        // 运行结果:(integer) 1

// append String_Key String_Value : 在指定 Redis 键的字符串值后追加 String_Value,返回追加后的字符串长度
append stringkey _append    // 运行结果:(integer) 19

// setbit String_Key offset value:设置指定 Redis 键的字符串值的二进制流中
//          偏移开头第一位的二进制位为 value(0 或 1),成功返回 1

在开始之前,我们先分析一波,stringkey 键的值现在是 string_value_append ,由前面的讨论可知,s 的二进制编码是 01110011,我们先看看运行结果:

setbit stringkey 6 0    // 运行结果:(integer) 1
get stringkey           // 运行结果:"qtring_value_append"

为什么 s 会变成 q 呢?因为 01110011 偏移 6 位,就是第七位,然后将它改为 0,也就是变成了这样:

顺序索引:  0    1    2    3    5    6    7    8
原二进制:  0    1    1    1    0    0    1    1    // 115 ASCII码表示为 s
今二进制:  0    1    1    1    0    0    0    1    // 113 ASCII码表示为 q

故原字符串的 s 变为了 q。

删除:del 命令

  // del Key :直接删除 Redis 中的一个 Key-Value 键值对,它可以用以删除任意 Redis Key-Value 对
  del stringkey

Hash 哈希

Hash 也是 Redis 的一种值类型,而且 Hash 类型不似 String 类型,它是一个集合,最多可有 2^32 - 1 个元素,每个元素又是一个键值对。接下来介绍一下如何在 Redis 中简单保存和获取一个 Hash 类型的值:

保存: hset 和 hmset 命令

  // hset Key Value_key Value_value : Key 是 Redis Key-Value 中的 Key,而 Value_key Value_value 则是 Value 集合中的一个元素
  hset book bookId_1 bookName_Java

  // 同理 hset 只能设置 Value 集合中的一个元素,hmset 则可同时设置多个 Value 集合元素
  // hmset Key Value_key1 Value_value1 [Value_key2 Value_value2] [...]
  hmset book bookId_1 bookName_Java bookId_2 bookName_C bookId_3 bookName_Python

查找:hget 、hmget、hgetall 、hexists、hlen、hkeys 和 hvals命令

  // 获取指定 Key 的 Hash 集合中的指定键的值
  hget book bookId_1
  运行结果:"bookName_Java"

  // hmget Hash_Key value_key1 [value_key2] [...] :查找集合中的指定元素(通过键指定)
  hmget book bookId_1 bookId_2 bookId_3
  运行结果:
  1) "bookName_Java"
  2) "bookName_C"
  3) "bookName_Python"

  // 获取指定 Key 的 Hash 集合中的所有键值对信息
  hgetall book
  运行结果: 1) "bookId_1"
            2) "bookName_Java"
            3) "bookId_2"
            4) "bookName_C"
            5) "bookId_3"
            6) "bookName_Python"

  // hexists Hash_Key value_key1: 键值对集合中是否存在指定键的元素,返回匹配的元素总数
  hexists book bookId_1
  运行结果:(integer) 1

  // hlen Hash_Key :返回键值对集合的元素总数
  hlen book
  运行结果:(integer) 3

  // hkeys Hash_Key :获取键值对集合中所有元素的键
  hkeys book
  运行结果:
  1) "bookId_1"
  2) "bookId_2"
  3) "bookId_3"

  // hvals Hash_Key :获取键值对集合中所有元素的值
  hvals book
   运行结果:
  1) "bookName_Java"
  2) "bookName_C"
  3) "bookName_Python"

修改:当要修改 Value 集合中的某个已存在的元素的键值对中的值时,可以重新保存覆盖原值。

    // hincrby Hash_Key value_key increment: 如果键值对集合中的指定元素的值是整型数据,
    //       那么可以使用此命令使其键增减 increment,返回修改后的数值
    // hincrbyfloat Hash_Key value_key increment: 如果键值对集合中的指定元素的值是浮点型数据,
    //       那么可以使用此命令使其键增减 increment,返回修改后的数值
    // 示例:
    hmset test int 1 float 2.0
    hincreby test int 5          // 运行结果:(integer) 6
    hincrbyfloat test float 8    // 运行结果:"10"

删除:当要删除 Value 集合中的元素时,可以使用 hdel 命令同时删除一个或者多个元素:

    // hdel Key Value_key1 [Value_key2] [...]
    hdel book bookId_1 bookId_2

List 列表

List 类型也是一个集合类型,但是它允许集合中有多个相同的元素(所以严格来说它并不是集合,故而称其为列表),而 Hash 类型虽也是集合类型,但其每个元素的键都不允许重复,List 类型集合中的元素也并非键值对,而是单值的,元素数量最多为 2^32 - 1 个,同时允许以队列的形式来操作集合列表。接下来了解一下如何保存和获取一个 List 类型的值:

保存:lpush 、 rpush 和 linsert 命令

    // 在集合列表左边,也就是队列头部前面顺序添加一个或多个元素
    // lpush Key value_1 [value_2] [...]
    lpush queue 1 2 3
    列表结果: 3 2 1

    // 在集合列表右边,也就是队列尾部后面顺序添加一个或多个元素
    // rpush Key value_1 [value_2] [...]
    rpush queue 1 2 3
    列表结果:3 2 1 1 2 3

    // 在指定的元素(通过值匹配而非索引)前或后插入一个元素,
    // 若有多个匹配以从左到右匹配到的第一个元素为准
    // linsert List_Key (before| after) pivot value
    linsert queue after 2 100
    列表结果:3 2 100 1 1 2 3

查找:lrange 和 lindex 命令

    // 可以先用 llen 命令了解队列长度
    // llen Key
    llen queue
    运行结果:(integer) 7

    // 按照从左到右的顺序遍历队列来查找所有元素或者在指定区间 [start, stop] 内的所有元素
    // 当 stop = -1 时表示遍历列表所有元素,注意 start 和 stop 都是指索引 index
    // lrange Key start stop
    lrange queue 0 -1
    运行结果: 1) "3"
              2) "2"
              3) "100"
              4) "1"
              5) "1"
              6) "2"
              7) "3"

    // 使用 lindex 命令可以查看列表中指定位置索引的元素值,等效于 queue[index]
    // 注意 index 是从 0 开始计数的,而不是如上面的运行结果一般从 1 开始
    // lindex List_Key index
    lindex queue 3
    运行结果:"1"

对于索引,Redis 有其自己的设定,除了大家所熟知的从前往后递增的从 0 开始的索引,还有从后往前递减的从 -1 开始的索引,暂且称其为逆序索引,所谓 -1 表示的是从后往前数列表中第一个元素,大概就是这样:

    数值索引:  0   1   2   3   4   5
    逆序索引: -6  -5  -4  -3  -2  -1
    元素集合:  3   2   1   1   2   3

所以 lrange queue 0 -1,之所以可以遍历整个队列是因为:索引 0 表示开始元素是队列第一个元素,索引 -1 表示结束元素是队列从后往前数的第一个元素,也就是最后一个元素,如此便把整个队列都包含进了队列里。

修改: lset 命令

    // lset 用来修改列表中指定索引的元素值
    // lset List_Key index value
    lset queue 3 1000
    列表结果:3 2 100 1000 1 2 3

删除:lpop、rpop、lrem 和 ltrim 命令

    // lpop List_Key :返回列表最左边的元素,即队头元素
    lpop queue
    运行结果:"3"
    列表结果:2 100 1000 1 2 3

    // rpop List_Key :返回列表最右边的元素,即队尾元素
    rpop queue
    运行结果:"3"
    列表结果:2 100 1000 1 2

    // lrem List_Key count value:移除指定数量(通过 count 指定)的指定元素(通过 value 匹配)
    // count > 0 时从左往右匹配 |count| 个元素; count < 0 时从右往左匹配 |count| 个元素; count = 0 时匹配所有元素
    // 返回移除的元素数量
    lrem queue -1 1
    运行结果:(integer) 1
    列表结果:2 100 1000 2

    // 又如
    lrem queue -2 2
    运行结果:(integer) 2
    列表结果:100 1000

    // ltrim key start stop :不在 [start, stop] 区间内的所有元素都删除, start < stop 时无动作
    ltrim queue 0 1
    列表结果:100 1000

Set 集合

List 类型允许集合中有重复的值,但是 Set 类型却不允许有重复的值,正如集合自身的定义,元素无序而唯一,元素数量同样地,不超过 2^32 - 1 个。下面简单介绍一下在 Redis 中如何保存和查找一个 Set 类型的值:

保存:sadd 命令

    // sadd Set_Key value1 [value2] [...] :往一个 Set 类型集合中添加一个或多个唯一元素,
    // 返回添加成功的元素数量
    sadd myset 1 2 3
    运行结果:(integer) 3

查找:scard 、smembers、sismember 和 srandmember 命令

    // scard Set_key:获取集合元素总数
    scard myset
    运行结果:(integer) 3

    // smembers Set_Key:获取集合中的所有元素
    smembers myset
    运行结果: 1) "1"
              2) "2"
              3) "3"

    // sismember Set_Key value:询问某个值是不是集合中的元素,返回值 0 表示不是
    sismember myset 5
    运行结果:(integer) 0

    // srandmember Set_Key [count]:count 可选的,缺省为 1,从集合中返回 count 个随机元素
    srandmember myset 2
    运行结果(多次执行结果会不一样): 1) "2"
                                    2) "1"

删除:spop 、srem 和 smove 命令

    // spop Set_Key : 移除集合中的一个随机元素并返回
    spop myset
    运行结果:"2"

    // srem Set_key value1 [value2] [...]:移除集合中一个或多个指定元素,返回移除成功的元素个数
    srem myset 2 3
    运行结果:(integer) 1

    // smove Set_Key_1 Set_Key_2 value : 将 Set_Key_1 集合中指定的元素(value)剪切到 Set_Key_2 集合中
    // 返回剪切成功的元素个数,0 为剪切失败
    smove myset yourset 2
    运行结果:(integer) 0

集合的专属特殊操作:交、并、差运算

    // 创建两个 Set 类型的集合
    sadd myset 1 2 3
    sadd yourset 1 5 6

    // 并运算: myset 并 yourset
    // sunion Set_Key_1 [Set_Key_2] [...] :返回多个集合的并集
    // sunionstore destination_Set_Key Set_Key_1 [Set_Key_2] [...] : 
    //      将多个集合的并集结果保存到 destination_Set_Key 中,并返回并集元素总数
    sunion myset yourset
    运行结果:
    1) "1"
    2) "2"
    3) "3"
    4) "5"
    5) "6"

    // 交运算: myset 交 yourset
    // sinter Set_Key_1 [Set_Key_2] [...] :返回多个集合的交集
    // sinterstore destination_Set_Key Set_Key_1 [Set_Key_2] [...] : 
    //      将多个集合的并集结果保存到 destination_Set_Key 中,并返回交集元素总数
    sinter myset yourset
    运行结果:
    1) "1"

    // 差运算: myset - yourset
    // sdiff Set_Key_1 [Set_Key_2] [...] :返回第一个集合与其他集合的差集,
    //      即将第一个集合后的所有集合先并起来,再与第一个集合进行差运算或者顺序做差运算
    // sdiffstore destination_Set_Key Set_Key_1 [Set_Key_2] [...] : 
    //      将第一个集合与其他集合的差集结果保存到 destination_Set_Key 中,并返回差集元素总数
    sdiff myset yourset
    运行结果:
    1) "2"
    2) "3"

Zset 有序集合

相比 Set 类型,它们的区别在于元素是否有序,Zset 类型的集合元素是有序的,而 Set 类型的集合元素是无序的,那它是如何确保有序的呢?答每个元素在新增时给它绑定了一个双浮点型的分数,集合中的元素就按照这个分数进行排序。同样的,我们来看一下在 Redis 中如何保存或者查找一个 Zset 类型:

保存: zadd 命令

    // zadd ZSet_Key score1 value1 [score2 value2] [...] : 往一个 Zset 集合中添加一个或多个带有分数的元素,
    //         返回加入成功的元素个数
    zadd myzset 1.0 one 2.0 two 3.0 three 3.0 three1 3.0 three2 3.0 three3
    运行结果:(integer) 6

查找:zcard、zcount、zlexcount、zrange、zrevrange、zrangebylex、zrangebyscore、zrevrangebyscore、zrank、zrevrank 和 zscore 命令

    // zcard ZSet_Key: 返回集合元素总数
    zcard myzset
    运行结果:(integer) 6

    // zcount ZSet_Key minscore maxscore : 返回分数在区间 [minscore, maxscore] 中的元素总数
    zcount myzset 0.5 2
    运行结果:(integer) 2

在这里要特别的讲一下,lex 是什么,它被译为字典,也就是在元素分数不一致时,按照分数顺序排,而分数一样时,按照字典顺序排,所谓字典顺序就比如 a-z, A-Z。

    // zlexcount ZSet_Key min max : 当集合中的元素分数都一样时,根据字典顺序排序,
    //          此命令将获取字典顺序在区间 [min, max] 中的元素总数,当下面选用 '(' 时表示开区间,
    //          min = '-' 或 '[ | (' + 一个字符串,max = '+' 或 '[ | (' + 一个字符串
    //
    // zrangebylex ZSet_Key min max [limit offset count]:根据字典顺序获取在区间 [min, max] 中的所有元素结果集,
    //          此命令也只有在集合中的元素分数都一样的情况下才生效
    //          limit offset count 为可选字段,limit 表示限制返回结果集的数量,
    //          offset 表示从结果集中偏移多少个元素,
    //          count 表示偏移后再取几个元素作为返回值
    // 示例:以一个分数全相同的 Zset 来测试
    zadd testlex 0 a 0 b 0 c 0 cc 0 d 0 e

    zlexcount testlex - +    // - + 表示无上下限
    运行结果:(integer) 6

    zlexcount testlex [cc [e  // 表示计算 [cc, e] 中的所有元素总数,同 C 语言字符串比较方法
    运行结果:(integer) 3

    zlexcount testlex [cc (e  // 表示计算 [cc, e) 中的所有元素总数,同 C 语言字符串比较方法
    运行结果:(integer) 2

    zrangebylex testlex - +    // 获取所有元素
    运行结果:
    1) "a"
    2) "b"
    3) "c"
    4) "cc"
    5) "d"
    6) "e"

    zrangebylex testlex [cc [e    // 获取区间 [cc, e) 中的所有元素
    运行结果:
    1) "cc"
    2) "d"
    3) "e"

    zrangebylex testlex - + limit 3 2    // 从开始位置偏移 3 个元素,再取 2 个元素作为结果集返回
    运行结果:
    1) "cc"
    2) "d"

集中了解完这个 lex 的概念后,就回到正轨来继续介绍 zrange、zrevrange、zrangebyscore、zrevrangebyscore、zrank、zrevrank 和 zscore 命令:

    // zrange ZSet_Key start stop [withscores]:获取指定下标区间 [start, stop] 的所有元素,withscores 表示是否携带分数
    //         start 和 stop 与在 List 类型中所了解的概念一样,是索引 index 值
    // zrevrange ZSet_Key start stop [withscores]: zrevrange 相当于把这个集合倒置了,比如 zrange 是升序排列,那么 zrevrange 就是降序排列。
    zrange myzset 0 -1 withscores
    运行结果:
     1) "one"
     2) "1"
     3) "two"
     4) "2"
     5) "three"
     6) "3"
     7) "three1"
     8) "3"
     9) "three2"
    10) "3"
    11) "three3"
    12) "3"

    zrange myzset 3 -2
    运行结果:
    1) "three1"
    2) "three2"

    zrevrange myzset 3 -2
    运行结果:
    1) "three"
    2) "two"

    // zrangebyscore ZSet_Key minscore maxscore [withscores] [limit offset count]: 获取集合中指定分数区间的元素,
    //       重复的字段就不再解释了,等会直接看例子
    // zrevrangebyscore ZSet_Key maxscore minscore [withscores] [limit offset count]: 原理同 zrevrange,
    //       注意分数区间变为了 [maxscore, minscore]
    zrangebyscore myzset 2.3 3.0 withscores limit 1 3
    运行结果:
    1) "three1"
    2) "3"
    3) "three2"
    4) "3"
    5) "three3"
    6) "3"

    zrevrangebyscore myzset 3.0 2.3 withscores limit 1 3
    运行结果:
    1) "three2"
    2) "3"
    3) "three1"
    4) "3"
    5) "three"
    6) "3"

    // zrank ZSet_Key member : 返回集合中指定元素的索引,从 0 开始
    // zrevrange ZSet_Key member : 同理,返回逆序排列中此元素的索引,也是从 0 开始
    zrank myzset three
    运行结果:(integer) 2

    zrevrank myzset three
    运行结果:(integer) 3

    // zscore ZSet_Key member :返回集合中指定元素的分数
    zscore myzset three
    运行结果:"3"

修改:zincrby 命令

    // zincrby ZSet_Key increment menmber : 将集合中指定元素的分数增加 increment,并返回此元素最终的分数
    zincrby myzset 10.5 one
    运行结果:"11.5"

删除:zrem、zremrangebylex、zremrangebyrank 和 zremrangebyscore 命令

    // zrem ZSet_Key member1 [member2] [...] :移除集合中一个或多个元素,返回成功移除的个数
    zrem myzset three1 three2
    运行结果:(integer) 2

    // zremrangebyscore ZSet_Key minscore maxscore:移除集合中指定分数闭区间内的所有元素,返回成功移除的个数
    zremrangebyscore myzset 1.35 2.88
    运行结果:(integer) 1

    // zremrangebyrank ZSet_Key start stop :移除集合中指定索引闭区间内的所有元素,返回成功移除的个数
    zremrangebyrank myzset 2 -1
    运行结果:(integer) 1

    // zremrangebylex ZSet_Key min max :移除集合(这个命令执行完后所有元素的分数都是 3,所以 lex 排序生效)
    //      中指定字典排序闭区间内的所有元素,返回成功移除的个数
    zremrangebylex myzset [three [three
    运行结果:(integer) 1 

集合的交并运算

首先,在原有基础上,执行以下命令,新增一个 ZSet 集合:

    zadd zset 1 one 2 two
    zadd myzset 1 one 2 two

然后先来看并运算:

    // zunionstore destination key_num ZSet_Key_1 [ZSet_Key2] [...] [weights weight1 [weight2] [...]] [aggregate (sum | min | max)]
    // destination 表示结果集存放到这里,key_num 表示指定数量的 ZSet 集合参与并运算,
    // weights 后面跟着 key_num 个数字,与前面 key_num 个 ZSet 集合一一对应,表示一个集合里的所有元素在合并的时候要乘以这个因子,缺省为 1
    // aggregate 表示合并时分布在不同集合中的相同元素的分数要怎么取,sum 表示累加,min 表示取最小的,max 取最大的,缺省为 sum
    // 返回新集合的元素总数,示例:
    zunionstore out 2 myzset zset weights 2 3 aggregate sum
    运行结果:(integer) 3

    zrange out 0 -1 withscores
    运行结果:
    1) "one"
    2) "5"
    3) "three3"
    4) "6"
    5) "two"
    6) "10"

交运算同理,示例:

    // zinterstore destination key_num ZSet_Key_1 [ZSet_Key2] [...] [weights weight1 [weight2] [...]] [aggregate (sum | min | max)]
    zinterstore in 2 myzset zset weights 2 3 aggregate sum
    运行结果:(integer) 2

    zrange in 0 -1 withscores
    运行结果:
    1) "one"
    2) "5"
    3) "two"
    4) "10"
posted @ 2022-04-08 22:19  lizhpn  阅读(59)  评论(0编辑  收藏  举报