redis 字符串操作

Jackey Redis 2,934 次浏览 , , 没有评论

字符串(string)

Redis 中最简单的数据结构,它既可以储存文字(比如 "hello world"),又可以储存数字(比如整数10086 和浮点数 3.14),还可以储存二进制数据(比如 10010100)。
Redis 为这几种类型的值分别设置了相应的操作命令,让用户可以针对不同的值做不同的处理。

为字符串键设置值

SET key value
将字符串键 key 的值设置为 value ,命令返回 OK 表示设置成功。
如果字符串键 key 已经存在,那么用新值覆盖原来的旧值。

redis> SET msg "hello world"
OK

redis> SET msg "goodbye" # 覆盖原来的值 "hello world"
OK

SET key value [NX|XX]

SET 命令还支持可选的 NX 选项和 XX 选项:
• 如果给定了 NX 选项,那么命令仅在键 key 不存在的情况下,才进行设置操作;如果键 key 已经存在,那么 SET ... NX 命令不做动作(不会覆盖旧值)。
• 如果给定了 XX 选项,那么命令仅在键 key 已经存在的情况下,才进行设置操作;如果键 key 不存在,那么 SET ... XX 命令不做动作(一定会覆盖旧值)。
在给定 NX 选项和 XX 选项的情况下,SET 命令在设置成功时返回 OK ,设置失败时返回 nil 。
redis> SET nx-str "this will fail" XX # 键不存在,指定 XX 选项导致设置失败
(nil)
redis> SET nx-str "this will success" NX # 键不存在,所以指定 NX 选项是可行的
OK
redis> SET nx-str "this will fail" NX # 键已经存在,指定 NX 选项导致设置失败
(nil)
redis> SET nx-str "this will success again!" XX # 键已经存在,指定 XX 选项是可行的
OK

获取字符串的值

GET key
返回字符串键 key 储存的值。

redis> SET msg "hello world"
OK
redis> GET msg
hello world
redis> SET number 10086
OK
redis> GET number
10086

仅在键不存在的情况下进行设置

SETNX key value
仅在键 key 不存在的情况下,将键 key 的值设置为 value ,效果和 SET key value NX 一样。
NX 的意思为“Not eXists”(不存在)。
键不存在并且设置成功时,命令返回 1 ;因为键已经存在而导致设置失败时,命令返回 0 。

redis> SETNX new-key "i am a new key!"
1
redis> SETNX new-key "another new key here!" # 键已经存在,设置失败
0
redis> GET new-key # 键的值没有改变
i am a new key!

同时设置或获取多个字符串键的值

命令效果
MSET key value [key value ...]一次为一个或多个字符串键设置值,效果和同时执行多个 SET 命令一样。
命令返回 OK 。
MGET key [key ...]一次返回一个或多个字符串 键的
值,效果和同时执行多个 GET 命
令一样。

一次设置多个不存在的键

MSETNX key value [key value ...]
只有在所有给定键都不存在的情况下, MSETNX 会为所有给定键设置值,效果和同时执行多个SETNX 一样。如果给定的键至少有一个是存在的,那么 MSETNX 将不执行任何设置操作。
返回 1 表示设置成功,返回 0 表示设置失败。复杂度为 O(N) , N 为给定的键数量。
redis> MSETNX nx-1 "hello" nx-2 "world" nx-3 "good luck"
1
redis> SET ex-key "bad key here"
OK
redis> MSETNX nx-4 "apple" nx-5 "banana" ex-key "cherry" nx-6 "durian"
0
因为 ex-key 键已经存在,所以第二个 MSETNX 会执行失败,所有键都不会被设置。

设置新值并返回旧值

GETSET key new-value
将字符串键的值设置为 new-value ,并返回字符串键在设置新值之前储存的旧值(old value)。
复杂度为 O(1) 。
redis> SET getset-str "i'm old value" # 先给字符串键设置一个值
OK
redis> GETSET getset-str "i'm new value" # 更新字符串键的值,并返回之前储存的旧值
i'm old value
redis> GET getset-str # 确认一下,新值已被设置
i'm new value

追加内容到字符串末尾

APPEND key value
将值 value 推入到字符串键 key 已储存内容的末尾。
O(N), 其中 N 为被推入值的长度。
redis> SET myPhone "nokia"
OK
redis> APPEND myPhone "-1110"
(integer) 10
redis> GET myPhone
"nokia-1110"

返回值的长度

STRLEN key
返回字符串键 key 储存的值的长度。
因为 Redis 会记录每个字符串值的长度,所以获取该值的复杂度为 O(1) 。
redis> SET msg "hello"
OK
redis> STRLEN msg
(integer) 5
redis> APPEND msg " world"
(integer) 11
redis> STRLEN msg
(integer) 11

索引

字符串的索引(index)以 0 为开始,从字符串的开头向字符串的结尾依次递增,字符串第一个字符的索引为 0 ,字符串最后一个字符的索引 为 N-1 ,其中 N 为字符串的长度。
除了(正数)索引之外,字符串 还有负数索引:负数索引以 -1 为开始,从字符串的结尾向字符串的开头依次递减,字符串的最后一个字符的索引 为 -N ,其中 N 为字符串的长度。

范围设置

SETRANGE key index value
从索引 index 开始,用 value 覆写(overwrite)给定键 key 所储存的字符串值。只接受正数索引。
命令返回覆写之后,字符串 值的长度。复杂度为 O(N), N 为 value 的长度。
redis> SET msg "hello"
OK
redis> SETRANGE msg 1 "appy"
(integer) 5
redis> GET msg
"happy"

范围取值

GETRANGE key start end
返回键 key 储存的字符串值中,位于 start 和 end 两个索引之间的内容(闭区间,start 和 end 会被包括
在内)。和 SETRANGE 只接受正数索引不同, GETRANGE 的索引可以是正数或者 负数。
复杂度为 O(N) , N 为被选中内容的长度。
redis> SET msg "hello world"
OK
redis> GETRANGE msg 0 4
"hello"
redis> GETRANGE msg -5 -1
"world"

设置和获取数字

只要储存在字符串键里面的值可以被解释为 64 位整数,或者 IEEE-754 标准的 64 位浮点数,那么用户就可以对这个字符串键执行针对数字值的命令。

能否执行数字值命令?原因
10086可以值可以被解释为整数
3.14可以值可以被解释为浮点数
+123可以值可以被解释为整数
123456789123456789123456789不可以值太大,没办法使用 64 位整数来储存
2.0e7不可以Redis 不解释以科学记数法表示的浮点数
123ABC不可以值包含文字
ABC不可以值为文字

增加或者减少数字的值

对于一个保存着数字的字符串 键 key ,我们可以使用 INCRBY 命令来增加它的值,或者使用 DECRBY命令来减少它的值。

命令效果
INCRBY key increment将 key 所储存的值加上增量 increment ,命令返回操作执行之后,键 key 的当前值。
DECRBY key decrement 将 key 所储存的值减去减量 decrement ,命令返回操作执行之后,键 key 的当前值。

如果执行 INCRBY 或者 DECRBY 时,键 key 不存在,那么命令会将 键 key 的值初始化为 0 ,然后再执行增加或者减少操作

INCRBY / DECRBY 示例

redis> INCRBY num 100 # 键 num 不存在,命令先将 num 的值初始化为 0 ,
(integer) 100 # 然后再执行加 100 操作
redis> INCRBY num 25 # 将值再加上 25
(integer) 125
redis> DECRBY num 10 # 将值减少 10
(integer) 115
redis> DECRBY num 50 # 将值减少 50
(integer) 65

增一和减一

因为针对数字值的增一和减一操作非常常 见,所以 Redis 特别为这两个操作创建了 INCR 命令和DECR 命令。

命令效果
INCR key等同于执行 INCRBY key 1
DECR key等同于执行 DECRBY key 1

redis> SET num 10
OK
redis> INCR num
(integer) 11
redis> DECR num
(integer) 10

浮点数的自增和自减

INCRBYFLOAT key increment
为字符串键 key 储存的值加上浮点数增量 increment ,命令返回操作执行之后,键 key 的值。
没有相应的 DECRBYFLOAT ,但可以通过给定负值来达到 DECRBYFLOAT 的效果。
复杂度为 O(1) 。
redis> SET num 10
OK
redis> INCRBYFLOAT num 3.14
"13.14"
redis> INCRBYFLOAT num -2.04 # 通过传递负值来达到做减法的效果
"11.1"

注意事项

即使字符串键储存的是数字值,它也可以执行 APPEND、STRLEN、SETRANGE 和 GETRANGE 。
当用户针对一个数字值执行这些命令的时候,Redis 会先将数字值转换为字符串,然后再执行命令。
redis> SET number 123
OK
redis> STRLEN number # 转换为 "123" ,然后计算这个字符串的长度
3
redis > APPEND number 456 # 转换为 "123" ,然后与 "456" 进行拼接
6
redis> GET number
123456

注意事项

一个英文字符只需要使用 单个字节来储存,而一个中文字符却需要使用多个字 节来储存。

STRLEN、SETRANGE 和 GETRANGE 都是为英文设置的,它们只会在字符为单个字节的情况下正常工作,而一旦我们储存的是类似中文这样的多字节字符,那么这三个命令就不再适用了。

STRLEN 示例
$ redis-cli --raw # 在 redis-cli 中使用中文时,必须打开 --raw 选项,才能正常显示中文
redis> SET msg "世界你好" # 设置四个中文字符
OK
redis> GET msg # 储存中文没有问题
世界你好
redis> STRLEN msg # 这里 STRLEN 显示了“世界你好”的字节长度为 12 字节
12 # 但我们真正想知道的是 msg 键里面包含多少个字符

不要使用 STRLEN、SETRANGE 和 GETRANGE 来处理中文。
例外情况:如果你想知道被 储存的中文包含多少个字节,那么可以使用 STRLEN 。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Go