Redis数据类型--String(字符串)

Redis的字符串和其他编程语言或者其他键值存储提供的字符串非常相似。一个key对应一个value。
string类型是二进制安全的,可以包含任何数据,比如jpg图片或者序列化的对象。从内部实现来看其实string可以看作byte数组,最大上限1G字节。
另外string类型可以被部分命令按int处理,比如incr等命令。
文档目前描述的内容以 Redis 2.8 版本为准。

SET

SET key value [EX seconds] [PX milliseconds] [NX|XX]
 将字符串值 value 关联到 key 。
 如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
 对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。

可选参数

EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。

返回值

SET 在设置操作成功完成时,才返回 OK 。如果设置了 NX 或者 XX ,但因为条件没达到而造成设置操作未执行,那么命令返回空批量回复(NULL Bulk Reply)。

示例

1
2
3
4
5
6
127.0.0.1:6379> SET key "value"
OK
127.0.0.1:6379> SET key "value1" EX 10086 XX
OK
127.0.0.1:6379> SET key "value1" PX 10086 NX
(nil)

SETBIT

SETBIT key offset value
 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
 位的设置或清除取决于 value 参数,可以是 0 也可以是 1 。
 当 key 不存在时,自动生成一个新的字符串值。
 字符串会进行伸展(grown)以确保它可以将 value 保存在指定的偏移量上。当字符串值进行伸展时,空白位置以 0 填充。
 offset 参数必须大于或等于 0 ,小于 2^32 (bit 映射被限制在 512 MB 之内)。

返回值

指定偏移量原来储存的位。

示例

1
2
3
4
5
6
127.0.0.1:6379> SETBIT bit 50 1
(integer) 0
127.0.0.1:6379> GETBIT bit 50
(integer) 1
127.0.0.1:6379> GETBIT bit 40
(integer) 0

SETEX

SETEX key seconds value
 将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。
 如果 key 已经存在, SETEX 命令将覆写旧值。

返回值

设置成功时返回 OK 。当 seconds 参数不合法时,返回一个错误。

示例

1
2
3
4
5
6
127.0.0.1:6379> SETEX key 50 "value"
OK
127.0.0.1:6379> GET key
"value"
127.0.0.1:6379> TTL key
(integer) 29

SETNX

SETNX key value
 将 key 的值设为 value ,当且仅当 key 不存在。
 若给定的 key 已经存在,则 SETNX 不做任何动作。
 SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。

返回值

设置成功,返回 1 。设置失败,返回 0 。

示例

1
2
3
4
127.0.0.1:6379> SETNX key "value"
(integer) 1
127.0.0.1:6379> SETNX key "value1"
(integer) 0

SETRANGE

SETRANGE key offset value
 用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始。
 不存在的 key 当作空白字符串处理。
 SETRANGE 命令会确保字符串足够长以便将 value 设置在指定的偏移量上,如果给定 key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但你设置的 offset 是 10 ),那么原字符和偏移量之间的空白将用零字节(zerobytes, “\x00” )来填充。
 注意你能使用的最大偏移量是 2^29-1(536870911) ,因为 Redis 字符串的大小被限制在 512 兆(megabytes)以内。如果你需要使用比这更大的空间,你可以使用多个 key 。

注意:当生成一个很长的字符串时,Redis 需要分配内存空间,该操作有时候可能会造成服务器阻塞(block)。在2010年的Macbook Pro上,设置偏移量为 536870911(512MB 内存分配),耗费约 300 毫秒, 设置偏移量为 134217728(128MB 内存分配),耗费约 80 毫秒,设置偏移量 33554432(32MB 内存分配),耗费约 30 毫秒,设置偏移量为 8388608(8MB 内存分配),耗费约 8 毫秒。 注意若首次内存分配成功之后,再对同一个 key 调用 SETRANGE 操作,无须再重新内存。

返回值

被 SETRANGE 修改之后,字符串的长度。

示例

1
2
3
4
5
6
7
127.0.0.1:6379> EXISTS empty_key
(integer) 0
127.0.0.1:6379> SETRANGE empty_key 5 "Redis!"
(integer) 11
127.0.0.1:6379> GET empty_key
"\x00\x00\x00\x00\x00Redis!"
127.0.0.1:6379>

GET

GET key
 返回 key 所关联的字符串值。
 如果 key 不存在那么返回特殊值 nil 。
 假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。

返回值

当 key 不存在时,返回 nil ,否则,返回 key 的值。如果 key 不是字符串类型,那么返回一个错误。

示例

1
2
3
4
127.0.0.1:6379> SET key "value"
OK
127.0.0.1:6379> GET key
"value"

GETBIT

GETBIT key offset
 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
 当 offset 比字符串值的长度大,或者 key 不存在时,返回 0 。

返回值

字符串值指定偏移量上的位(bit)。对不存在的 key 或者不存在的 offset 进行 GETBIT, 返回 0。

示例

1
2
3
4
5
6
7
8
127.0.0.1:6379> EXISTS bits
(integer) 0
127.0.0.1:6379> GETBIT bits 100
(integer) 0
127.0.0.1:6379> SETBIT bits 101 1
(integer) 0
127.0.0.1:6379> GETBIT bits 101
(integer) 1

GETRANGE

GETRANGE key start end
 返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。
 负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推。
 GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。

返回值

截取得出的子字符串。

示例

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> SET greeting "hello, my friend"
OK
127.0.0.1:6379> GETRANGE greeting 0 4 # 返回索引0-4的字符,包括4。
"hello"
127.0.0.1:6379> GETRANGE greeting -1 -5 # 不支持回绕操作
""
127.0.0.1:6379> GETRANGE greeting -3 -1 # 负数索引
"end"
127.0.0.1:6379> GETRANGE greeting 0 -1 # 从第一个到最后一个
"hello, my friend"
127.0.0.1:6379> GETRANGE greeting 0 1008611 # 值域超出部分被符略
"hello, my friend"

GETSET

GETSET key value
 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
 当 key 存在但不是字符串类型时,返回一个错误。

可用版本

版本>= 1.0.0

时间复杂度

O(1)

返回值

 返回给定 key 的旧值。
 当 key 没有旧值时,也即是, key 不存在时,返回 nil 。

示例

1
2
3
4
5
6
7
8
redis> GETSET db mongodb # 没有旧值,返回 nil
(nil)
redis> GET db
"mongodb"
redis> GETSET db redis # 返回旧值 mongodb
"mongodb"
redis> GET db
"redis"

APPEND

APPEND key value
 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。

可用版本

= 2.0.0

时间复杂度

平摊O(1)

返回值

追加 value 之后, key 中字符串的长度。

示例

1
2
3
4
5
6
7
8
9
10
# 对不存在的 key 执行 APPEND
redis> EXISTS myphone # 确保 myphone 不存在
(integer) 0
redis> APPEND myphone "nokia" # 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"
(integer) 5 # 字符长度
# 对已存在的字符串进行 APPEND
redis> APPEND myphone " - 1110" # 长度从 5 个字符增加到 12 个字符
(integer) 12
redis> GET myphone
"nokia - 1110"

BITCOUNT

BITCOUNT key [start] [end]
 计算给定字符串中,被设置为 1 的比特位的数量。
 一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。
 start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此类推。
 不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

可用版本

版本>= 2.6.0

时间复杂度

O(N)

返回值

被设置为 1 的位的数量。

示例

1
2
3
4
5
6
7
8
9
10
redis> BITCOUNT bits
(integer) 0
redis> SETBIT bits 0 1 # 0001
(integer) 0
redis> BITCOUNT bits
(integer) 1
redis> SETBIT bits 3 1 # 1001
(integer) 0
redis> BITCOUNT bits
(integer) 2

BITOP

BITOP operation destkey key [key …]
 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
 operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种:

  • BITOP AND destkey key [key …] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。
  • BITOP OR destkey key [key …] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。
  • BITOP XOR destkey key [key …] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。
  • BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey 。

 除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。

处理不同长度的字符串

当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。空的 key 也被看作是包含 0 的字符串序列。

可用版本

版本>= 2.6.0

时间复杂度

O(N)

返回值

保存到 destkey 的字符串的长度,和输入 key 中最长的字符串长度相等。

注意: BITOP 的复杂度为 O(N) ,当处理大型矩阵(matrix)或者进行大数据量的统计时,最好将任务指派到附属节点(slave)进行,避免阻塞主节点。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
redis> SETBIT bits-1 0 1 # bits-1 = 1001
(integer) 0
redis> SETBIT bits-1 3 1
(integer) 0
redis> SETBIT bits-2 0 1 # bits-2 = 1011
(integer) 0
redis> SETBIT bits-2 1 1
(integer) 0
redis> SETBIT bits-2 3 1
(integer) 0
redis> BITOP AND and-result bits-1 bits-2
(integer) 1
redis> GETBIT and-result 0 # and-result = 1001
(integer) 1
redis> GETBIT and-result 1
(integer) 0
redis> GETBIT and-result 2
(integer) 0
redis> GETBIT and-result 3
(integer) 1

DECR

DECR key
 将 key 中储存的数字值减一。
 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。
 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
 本操作的值限制在 64 位(bit)有符号数字表示之内。

可用版本

版本>= 1.0.0

时间复杂度

O(1)

返回值

执行 DECR 命令之后 key 的值。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 对存在的数字值 key 进行 DECR
redis> SET failure_times 10
OK
redis> DECR failure_times
(integer) 9
# 对不存在的 key 值进行 DECR
redis> EXISTS count
(integer) 0
redis> DECR count
(integer) -1
# 对存在但不是数值的 key 进行 DECR
redis> SET company YOUR_CODE_SUCKS.LLC
OK
redis> DECR company
(error) ERR value is not an integer or out of range

DECRBY

DECRBY key decrement
 将 key 所储存的值减去减量 decrement 。
 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 操作。
 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
 本操作的值限制在 64 位(bit)有符号数字表示之内。

可用版本

版本>= 1.0.0

时间复杂度

O(1)

返回值

减去 decrement 之后, key 的值。

示例

1
2
3
4
5
6
7
8
9
10
# 对已存在的 key 进行 DECRBY
redis> SET count 100
OK
redis> DECRBY count 20
(integer) 80
# 对不存在的 key 进行DECRBY
redis> EXISTS pages
(integer) 0
redis> DECRBY pages 10
(integer) -10

INCR

INCR key
 将 key 中储存的数字值增一。
 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
 本操作的值限制在 64 位(bit)有符号数字表示之内。

注意:这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,所以 key 内储存的字符串被解释为十进制 64 位有符号整数来执行 INCR 操作。

可用版本

版本>= 1.0.0

时间复杂度

O(1)

返回值

执行 INCR 命令之后 key 的值。

示例

1
2
3
4
5
6
redis> SET page_view 20
OK
redis> INCR page_view
(integer) 21
redis> GET page_view # 数字值在 Redis 中以字符串的形式保存
"21"

INCRBY

INCRBY key increment
 将 key 所储存的值加上增量 increment 。
 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。
 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
 本操作的值限制在 64 位(bit)有符号数字表示之内。

可用版本

版本>= 1.0.0

时间复杂度

O(1)

返回值

加上 increment 之后, key 的值。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# key 存在且是数字值
redis> SET rank 50
OK
redis> INCRBY rank 20
(integer) 70
redis> GET rank
"70"
# key 不存在时
redis> EXISTS counter
(integer) 0
redis> INCRBY counter 30
(integer) 30
redis> GET counter
"30"
# key 不是数字值时
redis> SET book "long long ago..."
OK
redis> INCRBY book 200
(error) ERR value is not an integer or out of range

INCRBYFLOAT

INCRBYFLOAT key increment
 为 key 中所储存的值加上浮点数增量 increment 。
 如果 key 不存在,那么 INCRBYFLOAT 会先将 key 的值设为 0 ,再执行加法操作。
 如果命令执行成功,那么 key 的值会被更新为(执行加法之后的)新值,并且新值会以字符串的形式返回给调用者。
 无论是 key 的值,还是增量 increment ,都可以使用像 2.0e7 、 3e5 、 90e-2 那样的指数符号(exponential notation)来表示,但是,执行 INCRBYFLOAT 命令之后的值总是以同样的形式储存,也即是,它们总是由一个数字,一个(可选的)小数点和一个任意位的小数部分组成(比如 3.14 、 69.768 ,诸如此类),小数部分尾随的 0 会被移除,如果有需要的话,还会将浮点数改为整数(比如 3.0 会被保存成 3 )。
 除此之外,无论加法计算所得的浮点数的实际精度有多长, INCRBYFLOAT 的计算结果也最多只能表示小数点的后十七位。

当以下任意一个条件发生时,返回一个错误:

  • key 的值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型)
  • key 当前的值或者给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number)

可用版本

版本>= 2.6.0

时间复杂度

O(1)

返回值

执行命令之后 key 的值。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 值和增量都不是指数符号
redis> SET mykey 10.50
OK
redis> INCRBYFLOAT mykey 0.1
"10.6"
# 值和增量都是指数符号
redis> SET mykey 314e-2
OK
redis> GET mykey # 用 SET 设置的值可以是指数符号
"314e-2"
redis> INCRBYFLOAT mykey 0 # 但执行 INCRBYFLOAT 之后格式会被改成非指数符号
"3.14"
# 可以对整数类型执行
redis> SET mykey 3
OK
redis> INCRBYFLOAT mykey 1.1
"4.1"
# 后跟的 0 会被移除
redis> SET mykey 3.0
OK
redis> GET mykey # SET 设置的值小数部分可以是 0
"3.0"
redis> INCRBYFLOAT mykey 1.000000000000000000000 # 但 INCRBYFLOAT 会将无用的 0 忽略掉,有需要的话,将浮点变为整数
"4"
redis> GET mykey
"4"

MGET

MGET key [key …]
 返回所有(一个或多个)给定 key 的值。
 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。

可用版本

版本>= 1.0.0

时间复杂度

O(N) , N 为给定 key 的数量。

返回值

一个包含所有给定 key 的值的列表。

示例

1
2
3
4
5
6
7
8
9
10
11
redis> SET redis redis.com
OK
redis> SET mongodb mongodb.org
OK
redis> MGET redis mongodb
1) "redis.com"
2) "mongodb.org"
redis> MGET redis mongodb mysql # 不存在的 mysql 返回 nil
1) "redis.com"
2) "mongodb.org"
3) (nil)

MSET

MSET key value [key value …]
 同时设置一个或多个 key-value 对。
 如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。
 MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。

可用版本

版本>= 1.0.1

时间复杂度

O(N), N 为要设置的 key 数量。

返回值

总是返回 OK (因为 MSET 不可能失败)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK
redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"
# MSET 覆盖旧值例子
redis> SET google "google.hk"
OK
redis> MSET google "google.com"
OK
redis> GET google
"google.com"

MSETNX

MSETNX key value [key value …]
 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
 即使只有一个给定 key 已存在, MSETNX 也会拒绝执行所有给定 key 的设置操作。
 MSETNX 是原子性的,因此它可以用作设置多个不同 key 表示不同字段(field)的唯一性逻辑对象(unique logic object),所有字段要么全被设置,要么全不被设置。

可用版本

版本>= 1.0.1

时间复杂度

O(N), N 为要设置的 key 的数量。

返回值

当所有 key 都成功设置,返回 1 。
如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 对不存在的 key 进行 MSETNX
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1
redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"
# MSET 的给定 key 当中有已存在的 key
redis> MSETNX rmdbs "Sqlite" language "python" # rmdbs 键已经存在,操作失败
(integer) 0
redis> EXISTS language # 因为 MSET 是原子性操作,language 没有被设置
(integer) 0
redis> GET rmdbs # rmdbs 也没有被修改
"MySQL"

PSETEX

PSETEX key milliseconds value
这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。

可用版本

版本>= 2.6.0

时间复杂度

O(1)

返回值

设置成功时返回 OK 。

示例

1
2
3
4
5
6
redis> PSETEX mykey 1000 "Hello"
OK
redis> PTTL mykey
(integer) 999
redis> GET mykey
"Hello"

STRLEN

STRLEN key
 返回 key 所储存的字符串值的长度。
 当 key 储存的不是字符串值时,返回一个错误。

可用版本

版本>= 2.2.0

复杂度

O(1)

返回值

字符串值的长度。
当 key 不存在时,返回 0 。

示例

1
2
3
4
5
6
7
8
# 获取字符串的长度
redis> SET mykey "Hello world"
OK
redis> STRLEN mykey
(integer) 11
# 不存在的 key 长度为 0
redis> STRLEN nonexisting
(integer) 0

Adhere to the original technology to share, your support will encourage me to continue to create!