zoukankan      html  css  js  c++  java
  • Redis教程7-键(key)常用命令使用参考3

    1.RENAMENX

    RENAMENX key newkey

    当且仅当 newkey 不存在时,将 key 改名为 newkey 。

    当 key 不存在时,返回一个错误。

    可用版本:>= 1.0.0

    时间复杂度:O(1)

    返回值:

    修改成功时,返回 1 。
    如果 newkey 已经存在,返回 0 。
    127.0.0.1:6379> renamenx name name2    // key不存在, 报错
    (error) ERR no such key
    127.0.0.1:6379> set name redis555    // 设置name
    OK
    127.0.0.1:6379> renamenx name name2    // newkey不存在, 操作成功
    (integer) 1
    127.0.0.1:6379> exists name    // name没了
    (integer) 0
    127.0.0.1:6379> get name2    // name2
    "redis555"
    127.0.0.1:6379> set name redis666    // 设置一个name
    OK
    127.0.0.1:6379> renamenx name name2    // newkey存在, 操作不成功
    (integer) 0
    127.0.0.1:6379> get name    // name存在
    "redis666"
    127.0.0.1:6379> get name2    // name2的值没有被覆盖
    "redis555"
    127.0.0.1:6379>

    2.RESTORE

    RESTORE key ttl serialized-value [REPLACE]

    反序列化给定的序列化值,并将它和给定的 key 关联。
    参数 ttl 以毫秒为单位为 key 设置生存时间;如果 ttl 为 0 ,那么不设置生存时间。

    RESTORE 在执行反序列化之前会先对序列化值的 RDB 版本和数据校验和进行检查,如果 RDB 版本不相同或者数据不完整的话,那么 RESTORE 会拒绝进行反序列化,并返回一个错误。

    如果键 key 已经存在, 并且给定了 REPLACE 选项, 那么使用反序列化得出的值来代替键 key 原有的值; 相反地, 如果键 key 已经存在, 但是没有给定 REPLACE 选项, 那么命令返回一个错误。

    更多信息可以参考 DUMP 命令。

    可用版本:>= 2.6.0

    时间复杂度:

    查找给定键的复杂度为 O(1) ,对键进行反序列化的复杂度为 O(N*M) ,其中 N 是构成 key 的 Redis 对象的数量,而 M 则是这些对象的平均大小。

    有序集合(sorted set)的反序列化复杂度为 O(N*M*log(N)) ,因为有序集合每次插入的复杂度为 O(log(N)) 。
    如果反序列化的对象是比较小的字符串,那么复杂度为 O(1) 。
    返回值:
    如果反序列化成功那么返回 OK ,否则返回一个错误。
    127.0.0.1:6379> set name redis666    // 设置name
    OK
    127.0.0.1:6379> dump name    // 序列化name
    "x00redis666	x00xf3x05$x80f*Mxf2"
    127.0.0.1:6379>
    127.0.0.1:6379> set name2 redis888    // 设置name2
    OK
    127.0.0.1:6379> restore name3 0 "x00redis666	x00xf3x05$x80f*Mxf2"    // 反序列化, 现在没有name3, 所以成功
    OK
    127.0.0.1:6379> get name3
    "redis666"
    127.0.0.1:6379> get name2
    "redis888"
    127.0.0.1:6379> get name
    "redis666"
    127.0.0.1:6379> restore name3 0 "x00redis666	x00xf3x05$x80f*Mxf2"    // 已经有了name3, 没有REPLACE, key重复, 所以失败
    (error) BUSYKEY Target key name already exists.
    127.0.0.1:6379> restore name3 0 "x00redis666	x00xf3x05$x80f*Mxf2" replace    // 使用replace覆盖name3, 但是序列化的name和name3的值都是redis666, 所以看不出来覆盖
    OK
    127.0.0.1:6379> get name3
    "redis666"
    127.0.0.1:6379> restore name2 0 "x00redis666	x00xf3x05$x80f*Mxf2" replace    // 使用replace覆盖name2
    OK
    127.0.0.1:6379> get name2    // name2原来是redis888, 现在是redis666
    "redis666"
    127.0.0.1:6379> keys *
    1) "name3"
    2) "name2"
    3) "name"
    127.0.0.1:6379>

    3.SORT

    SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]

    返回或保存给定列表list、集合set、有序集合zset  key 中经过排序的元素。

    排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比较。

    一般 SORT 用法

    最简单的 SORT 使用方法是 SORT key 和 SORT key DESC :

    • SORT key 返回键值从小到大排序的结果。
    • SORT key DESC 返回键值从大到小排序的结果。

    假设 today_cost 列表保存了今日的开销金额, 那么可以用 SORT 命令对它进行排序:

    127.0.0.1:6379> lpush today_cost 30 1.5 10 8
    (integer) 4
    127.0.0.1:6379> sort today_cost    // 排序
    1) "1.5"
    2) "8"
    3) "10"
    4) "30"
    127.0.0.1:6379> sort today_cost desc    // 降序排序
    1) "30"
    2) "10"
    3) "8"
    4) "1.5"
    127.0.0.1:6379>

    使用 ALPHA 修饰符对字符串进行排序

     因为 SORT 命令默认排序对象为数字, 当需要对字符串进行排序时, 需要显式地在 SORT 命令之后添加 ALPHA 修饰符, 否则会报错:

    localhost:6379> lpush names tom    // 列表中存储的是字符串
    (integer) 1
    localhost:6379> lpush names jerry
    (integer) 2
    localhost:6379> lpush names abc
    (integer) 3
    localhost:6379> lpush names vatt
    (integer) 4
    localhost:6379> sort names    // 默认排序报错
    (error) ERR One or more scores can't be converted into double
    localhost:6379> sort names desc    // 降序排序也是报错
    (error) ERR One or more scores can't be converted into double
    localhost:6379> sort names alpha    // 使用alpha进行排序
    1) "abc"
    2) "jerry"
    3) "tom"
    4) "vatt"
    localhost:6379> sort names desc alpha    // alpha降序
    1) "vatt"
    2) "tom"
    3) "jerry"
    4) "abc"
    localhost:6379>

    使用 LIMIT 修饰符限制返回结果

    排序之后返回元素的数量可以通过 LIMIT 修饰符进行限制, 修饰符接受 offset 和 count 两个参数:

    • offset 指定要跳过的元素数量。
    • count 指定跳过 offset 个指定的元素之后,要返回多少个对象。

    以下例子返回排序结果的前 5 个对象( offset 为 0 表示没有元素被跳过)。

    localhost:6379> lpush ages 1 3 2 5 4 7 6 9 8    // 创建列表ages
    (integer) 9
    localhost:6379> lrange ages 0 10
    1) "8"
    2) "9"
    3) "6"
    4) "7"
    5) "4"
    6) "5"
    7) "2"
    8) "3"
    9) "1"
    localhost:6379> sort ages asc limit 0 5    // 返回列表中最小的前5个值
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    localhost:6379> sort ages desc limit 0 5    // 返回列表中最大的前5个值
    1) "9"
    2) "8"
    3) "7"
    4) "6"
    5) "5"
    localhost:6379>

    使用外部 key 进行排序

    可以使用外部 key 的数据作为权重,代替默认的直接对比键值的方式来进行排序。

    假设现在有用户数据如下:

    uiduser_name_{uid}user_level_{uid}
    1 admin 9999
    2 jack 10
    3 peter 25
    4 mary 70

    以下代码将数据输入到 Redis 中:

    localhost:6379> lpush uid 1
    (integer) 1
    localhost:6379> set user_name_1 admin
    OK
    localhost:6379> set user_level_1 9999
    OK
    localhost:6379> lpush uid 2
    (integer) 1
    localhost:6379> set user_name_2 jack
    OK
    localhost:6379> set user_level_2 10
    OK
    localhost:6379> lpush uid 3
    (integer) 2
    localhost:6379> set user_name_3 peter
    OK
    localhost:6379> set user_level_3 25
    OK
    localhost:6379> lpush uid 4
    (integer) 3
    localhost:6379> set user_name_4 mary
    OK
    localhost:6379> set user_level_4 70
    OK
    localhost:6379>

    BY 选项

    默认情况下, SORT uid 直接按 uid 中的值排序:

    localhost:6379> sort uid
    1) "1"    // admin
    2) "2"    // jack
    3) "3"    // peter
    4) "4"    // mary
    localhost:6379> sort uid desc
    1) "4"
    2) "3"
    3) "2"
    4) "1"
    localhost:6379>

    通过使用 BY 选项,可以让 uid 按其他键的元素来排序。

    比如说, 以下代码让 uid 键按照 user_level_{uid} 的大小来排序:

    localhost:6379> sort uid by user_level_*    // 按照user_level_*升序排序
    1) "2"    // 10
    2) "3"    // 25
    3) "4"    // 70
    4) "1"    // 9999

    user_level_* 是一个占位符, 它先取出 uid 中的值, 然后再用这个值来查找相应的键。

    比如在对 uid 列表进行排序时, 程序就会先取出 uid 的值 1 、 2 、 3 、 4 , 然后使用 user_level_1 、 user_level_2 、 user_level_3 和 user_level_4的值作为排序 uid 的权重。

    再比如让uid键按照user_name_{uid}的大小进行降序排序, 需要注意使用alpha, 因为user_name_{uid}不是数值, 是字符串

    localhost:6379> sort uid by user_name_* desc alpha
    1) "3"
    2) "4"
    3) "2"
    4) "1"

    GET 选项

    使用 GET 选项, 可以根据排序的结果来取出相应的键值。

    比如说, 以下代码先排序 uid , 再取出键 user_name_{uid} 的值:

    localhost:6379> sort uid get user_name_*
    1) "admin"
    2) "jack"
    3) "peter"
    4) "mary"
    localhost:6379> sort uid get user_name_* desc
    1) "mary"
    2) "peter"
    3) "jack"
    4) "admin"

    组合使用 BY 和 GET

    通过组合使用 BY 和 GET , 可以让排序结果以更直观的方式显示出来。

    比如说, 以下代码先按 user_level_{uid} 来排序 uid 列表, 再取出相应的 user_name_{uid} 的值:

    localhost:6379> sort uid by user_level_* get user_name_*
    1) "jack"
    2) "peter"
    3) "mary"
    4) "admin"
    localhost:6379>

    现在的排序结果要比只使用 SORT uid BY user_level_* 要直观得多。

    获取多个外部键

    可以同时使用多个 GET 选项, 获取多个外部键的值。

    以下代码就按 uid 分别获取 user_level_{uid} 和 user_name_{uid} :

    localhost:6379> sort uid get user_level_* get user_name_*    // 获取外部键level和name
    1) "9999"
    2) "admin"
    3) "10"
    4) "jack"
    5) "25"
    6) "peter"
    7) "70"
    8) "mary"
    localhost:6379> sort uid desc get user_level_* get user_name_*    // 根据uid降序获取外部键
    1) "70"
    2) "mary"
    3) "25"
    4) "peter"
    5) "10"
    6) "jack"
    7) "9999"
    8) "admin"
    localhost:6379>

    GET 有一个额外的参数规则,那就是 —— 可以用 # 获取被排序键的值。

    以下代码就将 uid 的值、及其相应的 user_level_* 和 user_name_* 都返回为结果:

    localhost:6379> sort uid get # get user_level_* get user_name_*
     1) "1"
     2) "9999"
     3) "admin"
     4) "2"
     5) "10"
     6) "jack"
     7) "3"
     8) "25"
     9) "peter"
    10) "4"
    11) "70"
    12) "mary"
    localhost:6379> sort uid desc get # get user_level_* get user_name_*
     1) "4"
     2) "70"
     3) "mary"
     4) "3"
     5) "25"
     6) "peter"
     7) "2"
     8) "10"
     9) "jack"
    10) "1"
    11) "9999"
    12) "admin"

    获取外部键,但不进行排序

    通过将一个不存在的键作为参数传给 BY 选项, 可以让 SORT 跳过排序操作, 直接返回结果:

    localhost:6379> sort uid by aaa    // aaa外部键不存在, 跳过排序
    1) "4"
    2) "3"
    3) "2"
    4) "1"
    localhost:6379>

    这种用法在单独使用时,没什么实际用处。

    不过,通过将这种用法和 GET 选项配合, 就可以在不排序的情况下, 获取多个外部键, 相当于执行一个整合的获取操作(类似于 SQL 数据库的 join 关键字)。

    以下代码演示了,如何在不引起排序的情况下,使用 SORT 、 BY 和 GET 获取多个外部键:

    localhost:6379> sort uid by aaa get # get user_level_* get user_name_*
     1) "4"
     2) "70"
     3) "mary"
     4) "3"
     5) "25"
     6) "peter"
     7) "2"
     8) "10"
     9) "jack"
    10) "1"
    11) "9999"
    12) "admin"
    localhost:6379>

    将哈希表作为 GET 或 BY 的参数

    除了可以将字符串作为键之外, 哈希表也可以作为 GET 或 BY 选项的参数来使用。

    比如说,对于前面给出的用户信息表:

    localhost:6379> hmset user_info_1 name admin level 9999
    OK
    localhost:6379> hmset user_info_2 name jack level 10
    OK
    localhost:6379> hmset user_info_3 name peter level 25
    OK
    localhost:6379> hmset user_info_4 name mary level 70
    OK
    localhost:6379>

    之后, BY 和 GET 选项都可以用 key->field 的格式来获取哈希表中的域的值, 其中 key 表示哈希表键, 而 field 则表示哈希表的域:

    localhost:6379> sort uid by user_info_*->level
    1) "2"
    2) "3"
    3) "4"
    4) "1"
    localhost:6379> sort uid by user_info_*->level get user_info_*->name
    1) "jack"
    2) "peter"
    3) "mary"
    4) "admin"localhost:6379> sort uid by user_info_*->level get # get user_info_*->level get user_info_*->name
     1) "2"
     2) "10"
     3) "jack"
     4) "3"
     5) "25"
     6) "peter"
     7) "4"
     8) "70"
     9) "mary"
    10) "1"
    11) "9999"
    12) "admin"
    localhost:6379>

    保存排序结果

    默认情况下, SORT 操作只是简单地返回排序结果,并不进行任何保存操作。

    通过给 STORE 选项指定一个 key 参数,可以将排序结果保存到给定的键上。

    如果被指定的 key 已存在,那么原有的值将被排序结果覆盖。

    localhost:6379> lrange uid 0 -1
    1) "4"
    2) "3"
    3) "2"
    4) "1"
    localhost:6379> sort uid desc store uid_desc     // 缓存排序结果uid_desc
    (integer) 4
    localhost:6379> exists uid_desc
    (integer) 1
    localhost:6379> lrange uid_desc 0 -1
    1) "4"
    2) "3"
    3) "2"
    4) "1"
    localhost:6379>

    可以通过将 SORT 命令的执行结果保存,并用 EXPIRE 为结果设置生存时间,以此来产生一个 SORT 操作的结果缓存。

    这样就可以避免对 SORT 操作的频繁调用:只有当结果集过期时,才需要再调用一次 SORT 操作。

    另外,为了正确实现这一用法,你可能需要加锁以避免多个客户端同时进行缓存重建(也就是多个客户端,同一时间进行 SORT 操作,并保存为结果集),具体参见 SETNX 命令。

    返回值:

    没有使用 STORE 参数,返回列表形式的排序结果。
    使用 STORE 参数,返回排序结果的元素数量。
  • 相关阅读:
    CF1454F Array Partition
    leetcode1883 准时抵达会议现场的最小跳过休息次数
    leetcode1871 跳跃游戏 VII
    leetcode1872 石子游戏VIII
    CF1355C Count Triangles
    CF1245D Shichikuji and Power Grid
    CF1368C Even Picture
    CF1368D AND, OR and square sum
    CF1395C Boboniu and Bit Operations
    SpringBoot和开发热部署
  • 原文地址:https://www.cnblogs.com/no-celery/p/13696810.html
Copyright © 2011-2022 走看看