0%

Redis系列第二篇之String

前言

Redis为k-v形式的内存数据库,其v对应多种数据结构存储形式,String就是其中一种。让我们一起来学习String类型的数据结构以及String的各种命令吧!

String是Redis中最基本的数据类型,并且String是二进制安全的,也就是说String可以包含任意类型的数据,比如一张JPEG格式的图片或者是一个序列化后的Ruby对象。一个String类型的值最大长度可以是512MB。String类型能做的事情很多,比如:

  • 通过命令INCRDECRINCRBY,可以让String类型作为原子计数器。
  • 使用APPEND命令追加字符串。
  • 通过命令GETRANGESETRANGE可以让String作为一个随机访问向量。
  • 利用很小的空间对大量数据进行编码或者通过命令GETBITSETBIT创建布隆过滤器。

APPEND key value

  • 可用版本: v2.0.0开始
  • 时间复杂度: O(1)
  • 解释: 如果key早已存在并且存储类型为字符串,此命令将value附加到该string末尾。如果key不存在,Redis将会创建该key并设置为空字符串,因此在这种特殊情况下APPENDSET相似。
  • 返回值: Integer(整型),返回附加操作后的字符串长度
  • 时间序列模式
    APPEND命令可以用来创建一个由固定大小的样品组成的非常紧凑的列表,这样的列表被称为时间序列,每当一个新的样品到达时我们可以用下面的命令来存储它:
    APPEND timeseries "fixed-size" sample
    访问时间出列中单独的元素并不困难:
    • STRLEN可以用来获取样品的数量
    • GETRANGE允许随机访问元素。如果时间序列具有相关联的时间信息,我们可以轻松的通过GETRANGE与Redis v2.6中可用的Lua脚本引擎相结合来轻松实现二进制搜索以获取范围。
    • SETRANGE可以用来覆盖一个存在的时间序列
      这种模式的局限性是被强制在append-only操作中,因为Redis目前缺少可以裁剪string对象的命令所以没有办法将时间序列裁剪为指定大小。然而以这种方式存储的时间序列的空间效率是显著的。
      提示:可以根据当前的Unix时间切换到不同的键,这样每个键可以只有相对少量的样本,避免处理非常大的键,并使这种模式更友好分布在多个Redis实例中

DECR key

  • 可用版本: v1.0.0开始
  • 时间复杂度: O(1)
  • 解释: 将存储在key的值减1。如果key不存在,在执行操作之前将会被置为0,如果key包含错误类型的值或者包含一个不能表示为整数的值,将会返回错误。此操作仅限于64位有符号整数。
  • 返回值: Integer(整型),返回减法操作后的值

DECRBY key decrement

  • 可用版本: v1.0.0开始
  • 时间复杂度: O(1)
  • 解释:DECR命令同为减法操作,不同的是DECR为减一,而DECRBY则是减去指定的变量,如果decrement为负数,则与INCRBY功能相同。如果key不存在,则在执行操作之前会将key置为0,如果key包含错误类型的值或者包含一个不能表示为整数的值,将会返回错误。此操作仅限于64位有符号整数。
  • 返回值: Integer(整型),返回操作后的值

GET key

  • 可用版本: v1.0.0开始
  • 时间复杂度: O(1)
  • 解释: 获取key对应的value,如果key不存在将会返回nil。GET只能操作string类型,如果key存储的不是string类型,命令将会返回错误。
  • 返回值: Bulk String(批量字符串),返回key对应的value,如果key不存在将会返回nil。

GETDEL key

  • 可用版本: v6.2.0开始
  • 时间复杂度: O(1)
  • 解释: 获取key对应的值并且删除key(只能操作于string类型)
  • 返回值: Bulk String(批量字符串),如果key不存在返回nil。如果key不是string类型,返回错误。

GETEX key [ EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | PERSIST]

  • 可用版本: v6.2.0开始
  • 时间复杂度: O(1)
  • 解释: 获取key的值,同时可以选择设置key的有效期。
  • 选项说明:
    • EX 以秒为单位设置key的有效期
    • PX 以毫秒为单位设置key的有效期
    • EXAT 将有效期设置为精确到秒的时间戳
    • PXAT 将有效期设置为精确到毫秒的时间戳
    • PERSIST 移除相关联的key的有效期
  • 返回值: Bulk String(批量字符串),key不存在返回nil,否则返回key对应的value

GETRANGE key start end

  • 可用版本: v2.4.0开始
  • 时间复杂度: O(N),其中N为返回字符串的长度。
  • 解释: 返回存储在key中字符串的子串,子串由偏移量startend组成的闭区间决定,如果偏移量为负数,表示从字符串的结尾开始便宜:-1表示最后一个字符,-2表示倒数第二个字符等。如果偏移量超出字符串长度范围,则将会被限制在字符串长度范围内。
  • 返回值: Bulk String(批量字符串)

GETSET key value

  • 可用版本: v1.0.0开始,从v6.2.0开始,此命令被视为废弃,可以被带有GET选项的SET命令替代
  • 时间复杂度: O(1)
  • 解释: 设置key的值的同时返回key存储的旧值。如果key持有的不是string类型将会返回错误。SET成功后,key之前所有的有效期将会被丢弃。
  • 设计模式: GETSET可以与INCR一起用于原子复位计数。比如:当有程序检测到有事件发生时,可以调用INCR命令,如果需要获取并重置计数器的值时,可以调用GETSET命令。
  • 返回值: Bulk String(批量字符串),返回存储在key中的旧值或者nil(当key不存在时)。

INCR key

  • 可用版本: v1.0.0开始
  • 时间复杂度: O(1)
  • 解释: 将存储在key中的值加1,如果key不存在则命令在执行操作前会先将key的值置为0。如果key持有的数据类型不是string或者无法表示为一个整数时将会返回错误。同时此命令被限制在操作64位有符号整数范围内。
  • 返回值: Integer(整型),返回加1操作后的值

INCRBY key increment

  • 可用版本: v1.0.0开始
  • 时间复杂度: O(1)
  • 解释: 此命令与INCR相似,不同之处在于此命令将由调用者指定增量,如果增量为1,则与INCR命令功能一样。
  • 返回值: Integer(整型),返回加法操作后的值

INCRBYFLOAT key increment

  • 可用版本: v2.6.0开始
  • 时间复杂度: O(1)
  • 解释: 与命令INCRBY key increment相似,不同的是此命令增量可以设置为双精度浮点数(float),如果增量被指定为负数,则表示减法(默认加法操作)。如果key不存在,则命令在执行操作之前将会把key置为0,如果发生以下情况之一,将会返回错误:
    • key持有的错误类型的值(非string类型)
    • key当前持有的值或者指定的增量(increment)无法被解析为双精度浮点类型
      字符串键中已经包含的值和增量参数都可以选择以指数表示法提供,但是增量后计算的值始终以相同的格式存储:一个整数后跟(如果需要)一个点,以及表示数字的小数部分的可变位数。始终删除尾随零,无论计算的实际内部精度如何,输出的精度都固定在小数点后17位。
  • 返回值: Bulk String(批量字符串),返回命令执行操作后key所持有的值

LCS key1 key2 [LEN] [IDX] [MINMATCHLEN len] [WITHMATCHLEN]

  • 可用版本: v7.0.0开始
  • 时间复杂度: O(N*M),其中N为s1的长度,M为s2的长度
  • 解释: LCS命令实现最长公共子序列算法,与最长公共字符串算法不同的是,最长公共子序列算法在字符串中匹配的字符不需要是连续的,例如字符串faofo的最长公共子序列结果为foLCS命令在计算两个字符串有多相似时是非常有用的,比如计算DNA序列的相似程度。
  • 选项说明:
    • LEN 返回匹配结果的长度
    • IDX 返回每个匹配结果的匹配位置
    • MINMATCHLEN 限制匹配列表的最小长度
    • WITHMATCHLENIDX搭配使用,同时返回匹配长度
  • 返回值:
    • 没有指定修饰符:返回表示匹配到的最长子序列的Bulk String(批量字符串)
    • 如果指定了LEN修饰符将会返回最长子序列的长度
    • 如果指定了IDX修饰符,将会返回一个数组,其中包含LCS长度和两个字符串(s1,s2)中的所有范围、每个字符串的开始和结束偏移量,其中有匹配项。当给定 WITHMATCHLEN 时,表示匹配的每个数组也将具有匹配的长度

MGET key [key …]

  • 可用版本: v1.0.0开始
  • 时间复杂度: O(N),N为给定key的数量
  • 解释: 返回指定key(s)的值,对于不存在的key或者持有值不是string的key,将会返回nil,命令总是成功。
  • 返回值: Array(数组),返回由指定key(s )的值组成的数组

MSET key value [ key value …]

  • 可用版本: v1.0.1开始
  • 时间复杂度: O(N),N为key的数量
  • 解释: 批量设置key-value键值对。如果key存在,命令将会用新值替换key的旧值,MSET操作是原子性的。
  • 返回值: Simple String(简单字符串),命令总是返回OK

MSETNX key value [ key value …]

  • 可用版本: v1.0.1开始
  • 时间复杂度: O(N),N为key的数量
  • 解释:MSET功能一样,批量设置key-value键值对,不同的是如果指定的key已经存在MSETNX不会对于该key不会执行任何操作。同样,MSETNX也是原子性的
  • 返回值: Integer(整型)
    • 如果所有给定的key都被设置了则返回1
    • 如果没有key被设置则返回0

PSETEX key milliseconds value

  • 可用版本: v2.6.0开始
  • 时间复杂度: O(1)
  • 解释: 以毫秒为单位设置key的有效期
  • 返回值: Simple String(简单字符串),返回OK

SET key value [ NX | XX] [GET] [ EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]

  • 可用版本: v1.0.0开始
  • 历史:
    • v2.6.12开始支持EXPXNXXX选项
    • v6.0.0开始支持KEEPTTL选项
    • v6.2.0开始支持GETEXATPXAT选项
    • v7.0.0开始支持NXGET一起使用
  • 时间复杂度: O(1)
  • 解释: 将key设置为字符串value,如果key早已存在,无论旧值类型是什么,命令都将会覆盖旧值。执行操作之前的任何有效期都会被丢弃。
  • 选项说明:
    • EX 以秒为单位设置key的有效期为多少秒
    • PX 以毫秒为单位设置key的有效期为多少毫秒
    • EXAT 将key的有效截止时间点设置为精确到秒的时间戳
    • PXAT 将key的有效截止时间点设置为精确到毫秒的时间戳
    • NX 只有当key不存在时才设置
    • XX 只有当key已经存在时才设置
    • KEEPTTL 保留key既有的有效期
    • GET 返回key的旧值,如果key不存在则返回nil。如果key所持有的的旧值不是string类型,则终止SET操作。
  • 返回值:
    • Simple String(简单字符串):如果SET正确执行将返回OK
    • Null Reply(nil): 如果用户指定了NX或者XX选项,并且SET操作没有被执行则返回nil
      如果调用方指定了GET选项,将会以下面两种形式返回(无论SET命令是否执行):
    • Bulk String(批量字符串):如果key存在,返回key对应的旧值
    • Null Reply(nil):如果key不存在返回nil
  • 模式: 命令SET resource-name anystring NX EX max-lock-time是使用Redis实现锁的一种简单方式。客户端可以通过上述命令返回的OK获得锁(或者当返回nil时过一段时间再重试),并且通过命令DEL移除锁。
    当有效期到达后锁将自动释放。可以通过以下两点来使锁系统更加健壮:
    • 设置随机字符串(Token)而不是设置固定字符串
    • 通过脚本当Token匹配时才删除key而不是简单的通过DEL命令移除锁
      上述两点避免了当锁过期后,客户端再次尝试释放另一个客户端创建的锁。

SETEX key seconds value

  • 可用版本: v2.0.0开始
  • 时间复杂度: O(1)
  • 解释: 将key的值设置为字符串value,同时设置key的有效期为指定的秒数,如果秒数不可用将会返回错误。SETEX是原子操作。
  • 返回值: Simple String(简单字符串)

SETNX key value

  • 可用版本: v1.0.0开始
  • 时间复杂度: O(1)
  • 解释: 如果key不存在则将key的值设置为字符串value,如果key早已存在则不执行任何操作。
  • 返回值: Integer(整型)
    • 如果key被设置了返回1
    • 如果key没被设置返回0

SETRANGE key offset value

  • 可用版本: v2.2.0开始
  • 时间复杂度: 如果字符串很小,不计算拷贝字符串带来的开销时时间复杂度为O(1),否则时间复杂度为O(M),M为value的长度
  • 解释: 从指定offset开始到结尾的覆盖key持有的字符串值,如果offset大于key持有字符串的当前长度,则用零字节填充字符串以使offset适合,不存在的键被视为空字符串,因此此命令将确保它包含足够大的字符串以能够在偏移量处设置值。
    注意,offset可以设置的最大值为2^29-1(536870911),因为Redis字符串类型最大长度为512MB,如果需要增长超过这个限制,可以使用多个key。
  • 返回值: Integer(整型),返回命令执行后key持有的字符串的长度。

STRLEN key

  • 可用版本: v2.2.0开始
  • 时间复杂度: O(1)
  • 解释: 返回key持有的字符串的长度,如果value不是字符串类型,则返回错误
  • 返回值: Integer(整型),返回key对应字符串的长度,如果key不存在则返回0

SUBSTR key start end

  • 可用版本: v1.0.0开始,从Redis v2.0.0开始此命令被视为废弃
  • 时间复杂度: O(N),其中N为返回的字符串的长度
  • 解释: 返回key持有的字符串值的子串,子串由startend决定组成的闭区间决定,负数的偏移量表示从字符串尾部开始计算偏移量,如-1表示字符串最后一个字符。
  • 返回值: Bulk String(批量字符串),返回子串

参考资料

Redis String