前言
Redis为k-v形式的内存数据库,其v对应多种数据结构存储形式,String就是其中一种。让我们一起来学习String
类型的数据结构以及String
的各种命令吧!
String是Redis中最基本的数据类型,并且String是二进制安全的,也就是说String可以包含任意类型的数据,比如一张JPEG
格式的图片或者是一个序列化后的Ruby对象。一个String类型的值最大长度可以是512MB。String类型能做的事情很多,比如:
- 通过命令
INCR
,DECR
,INCRBY
,可以让String类型作为原子计数器。 - 使用
APPEND
命令追加字符串。 - 通过命令
GETRANGE
和SETRANGE
可以让String作为一个随机访问向量。 - 利用很小的空间对大量数据进行编码或者通过命令
GETBIT
和SETBIT
创建布隆过滤器。
APPEND key value
- 可用版本: v2.0.0开始
- 时间复杂度: O(1)
- 解释: 如果key早已存在并且存储类型为字符串,此命令将value附加到该string末尾。如果key不存在,Redis将会创建该key并设置为空字符串,因此在这种特殊情况下
APPEND
与SET
相似。 - 返回值: 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中字符串的子串,子串由偏移量
start
和end
组成的闭区间决定,如果偏移量为负数,表示从字符串的结尾开始便宜:-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
命令实现最长公共子序列算法,与最长公共字符串算法不同的是,最长公共子序列算法在字符串中匹配的字符不需要是连续的,例如字符串fao
和fo
的最长公共子序列结果为fo
。LCS
命令在计算两个字符串有多相似时是非常有用的,比如计算DNA序列的相似程度。 - 选项说明:
LEN
返回匹配结果的长度IDX
返回每个匹配结果的匹配位置MINMATCHLEN
限制匹配列表的最小长度WITHMATCHLEN
与IDX
搭配使用,同时返回匹配长度
- 返回值:
- 没有指定修饰符:返回表示匹配到的最长子序列的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开始支持
EX
,PX
,NX
和XX
选项 - v6.0.0开始支持
KEEPTTL
选项 - v6.2.0开始支持
GET
,EXAT
和PXAT
选项 - v7.0.0开始支持
NX
和GET
一起使用
- v2.6.12开始支持
- 时间复杂度: 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
- Simple String(简单字符串):如果
- 模式: 命令
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持有的字符串值的子串,子串由
start
和end
决定组成的闭区间决定,负数的偏移量表示从字符串尾部开始计算偏移量,如-1表示字符串最后一个字符。 - 返回值: Bulk String(批量字符串),返回子串