字符串

  • 常用字符串存取

  • 常用数字存取

  • 二进制数据存取

  • 常见应用场景

Redis中最简单的数据结构,它既可以储存文本,又可以储存数字,还可以储存二进制数据(比如 10010100)。

常用字符串存取

SET key value

将字符串键 key 的值设置为 value ,命令返回 OK 表示设置成功。

如果字符串键 key 已经存在,那么用新值覆盖原来的旧值。

复杂度为 O(1)。

SET key value [NX|XX]

SET 命令还支持可选的 NX 选项和 XX 选项:

  • 如果给定了 NX 选项,那么命令仅在键 key 不存在的情况下,才进行设置操作(不会覆盖旧值)。

  • 如果给定了 XX 选项,那么命令仅在键 key 已经存在的情况下,才进行设置操作(一定会覆盖旧值)。

  • 在给定 NX 选项和 XX 选项的情况下,SET 命令在设置成功时返回 OK ,设置失败时返回 nil 。

SETNX key value

仅在键不存在的情况下进行设置,将键 key 的值设置为 value ,效果和 SET key value NX 一样。

NX 的意思为“Not eXists”(不存在)。

键不存在并且设置成功时,命令返回1;因为键已经存在而导致设置失败时,命令返回0。

复杂度为 O(1)。

GET key

获取字符串的值。

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

复杂度为 O(1)。

MSET key value [key value ...]

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

一次为一个或多个字符串键设置值,效果和同时执行多个 SET 命令一样。命令返回 OK 。

复杂度为 O(N),N为要设置的字符串键数量。

MGET key [key ...]

一次返回一个或多个字符串键的值,效果和同时执行多个 GET 命令一样。

复杂度为 O(N),N 为要获取的字符串键数量。

MSETNX key value [key value ...]

一次设置多个不存在的键

只有在所有给定键都不存在的情况下,MSETNX 会为所有给定键设置值,效果和同时执行多个 SETNX 一样。如果给定的键至少有一个是存在的,那么

MSETNX 将不执行任何设置操作。返回 1 表示设置成功,返回 0 表示设置失败。

复杂度为 O(N) , N 为给定的键数量。

GETSET key new-value

设置新值并返回旧值

将字符串键的值设置为 new-value ,并返回字符串键在设置新值之前储存的旧值(old value)。

复杂度为 O(1) 。

APPEND key value

追加内容到字符串末尾

将值 value 推入到字符串键 key 已储存内容的末尾。

复杂度为 O(N), 其中 N 为被推入值的长度。

STRLEN key

返回值的长度

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

复杂度为 O(1) ,因为 Redis 会记录每个字符串值的长度。

索引和范围

  • 字符串的索引(index)以 0 为开始,从字符串的开头向字符串的结尾依次递增

  • 字符串第一个字符的索引为 0 ,字符串最后一个字符的索引为 N-1 ,其中 N 为字符串的长度。

  • 除了(正数)索引之外,字符串还有负数索引:负数索引以 -1 为开始,从字符串的结尾向字符串的开头依次递减,字符串的最后一个字符的索引

    为 -N ,其中 N 为字符串的长度。

SETRANGE key index value

范围设置

从索引 index 开始,用 value 覆写(overwrite)给定键 key 所储存的字符串值。只接受正数索引。命令返回覆写之后,字符串值的长度。

复杂度为 O(N), N 为 value 的长度。

GETRANGE key start end

范围取值

返回键 key 储存的字符串值中,位于 start 和 end 两个索引之间的内容(闭区间,start 和 end 会被包括在内)。和 SETRANGE

只接受正数索引不同,GETRANGE 的索引可以是正数或者负数。

复杂度为 O(N) , N 为被选中内容的长度。

常用数字存取

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

INCRBY key increment

增加指定数字的值

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

将 key 所储存的值加上增量 increment,命令返回操作执行之后,键 key 的当前值。

复杂度为 O(1)。

DECRBY key decrement

减少指定数字的值

将 key 所储存的值减去减量 decrement ,命令返回操作执行之后,键 key 的当前值。

复杂度为 O(1)。

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

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

  • INCR key 等同于执行 INCRBY key 1

  • DECR key 等同于执行 DECRBY key 1

INCRBYFLOAT key increment

浮点数的自增和自减

为字符串键 key 储存的值加上浮点数增量 increment ,命令返回操作执行之后,键 key 的值。

没有相应的 DECRBYFLOAT ,但可以通过给定负值来达到 DECRBYFLOAT 的效果。

复杂度为 O(1) 。

注意事项

  • 即使字符串键储存的是数字值,它也可以执行 APPEND、STRLEN、SETRANGE 和 GETRANGE 。

  • 当用户针对一个数字值执行这些命令的时候,Redis 会先将数字值转换为字符串,然后再执行命令。

二进制数据存取

一个字节由8个二进制位组成,利用位操作可以非常紧凑的存储布尔值。

比如网站的每个用户都有一个递增的整数ID,如果使用一个字符串类型键配合位操作来记录每个用户的性别,1和0表示男女,那么记录100万个用户的性别只需占用100KB多的空间。

由于GETBIT,SETBIT的时间复杂度都是O(1),所以读取二进制位值性能很高。

二进制位的索引

和储存文字时一样,字符串键在储存二进制位时,索引也是从 0 开始的。

但是和储存文字时,索引从左到右依次递增不同,当字符串键储存的是二进制位时,二进制位的索引会从左到右依次递减。

SETBIT key index value

设置二进制位的值 将给定索引上的二进制位的值设置为 value ,命令返回被设置的位原来储存的旧值。

复杂度为 O(1) 。

GETBIT key index

获取二进制位的值 返回给定索引上的二进制位的值。

复杂度为 O(1) 。

BITCOUNT key [start] [end]

计算值为 1 的二进制位的数量

计算并返回字符串键储存的值中,被设置为 1 的二进制位的数量。

一般情况下,给定的整个字符串键都会进行计数操作,但通过指定额外的 start 或 end 参数,可以让计数只在特定索引范围的位上进行。

start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个位,而 -2表示倒数第二个位,以此类推。

复杂度为 O(N) ,其中 N 为被计算二进制位的数量。

BITOP operation destkey key [key ...]

二进制位运算

对一个或多个保存二进制位的字符串键执行位元操作,并将结果保存到 destkey 上。

operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种

除了 NOT 操作之外,其他操作都可以接受一个或以上数量的 key 作为输入。

复杂度为 O(N) , N 为进行计算的二进制位数量的总和。

命令的返回值为计算所得结果的字节长度,相当于对 destkey 执行 STRLEN 。

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

常用应用场景

缓存高频请求网页

对于一个网站来说,如果某个页面经常会被访问到,或者创建页面时耗费的资源比较多(比如需要多次访问数据库、生成时间比较长,等等),可以使用

Redis 将这个页面缓存起来,减轻网站的负担,降低网站的延迟值。

程序尝试从缓存里面获取被缓存的页面数据,如果缓存存在,直接返回缓存数据;页面没有被缓存,生成页面并缓存页面,方便下次访问使用缓存数据。

一般情况下,会根据页面更新的频率,设置缓存的有效期,既保证程序高速响应,又能即时更新。

在线人数统计

通常每个用户都有一个唯一的数字id,所以我们可以在用户 id 和二进制位的索引之间进行关联:

  • 如果 id 为 N 的用户在线,我们就将索引为 N 的二进制位的值设置为 1 。

  • 如果索引为 N 的二进制位的值为 0 ,这表示 id 为 N 用户不在线。

  • 使用 BITCOUNT 可以统计有多少个用户在线。

  • 通过为每段时间分别储存一个二进制值,我们就可以为每段时间都记录在线用户的数量。(每小时创建一个键或者每天创建一个键,诸如此类。)

储存中文时的注意事项

STRLEN、SETRANGE 和 GETRANGE 不适用于中文

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

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

STRLEN 示例



# 在 redis-cli 中使用中文时,必须打开 --raw 选项,才能正常显示中文

redis-cli --raw

redis>  SET msg "世界你好" # 设置四个中文字符

OK

redis>  GET msg # 世界你好

redis>  STRLEN msg # 12 这里 STRLEN 显示了“世界你好”的字节长度为 12 字节 但我们真正想知道的是 msg 键里面包含多少个字符

SETRANGE 和 GETRANGE 示例

SETRANGE 和 GETRANGE 的情况也是类似的:因为这两个命令所使用的索引是根据字节而不是字符来编排的,所以调用 SETRANGE 或者

GETRANGE 来处理中文,得不到我们想要的结果。


redis>  SET msg "世界你好"

OK

redis>  GETRANGE msg 2 3 # 试图获取 "你好" �

redis>  SETRANGE msg 2 "欢迎你" # 试图构建 "世界欢迎你",其中"欢迎你"为 9 字节长 12

redis>  GET msg # ��欢迎你�

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

  • 每个字符串键可以保存一个值,这个值可以是文字、整数、浮点数或者二进制数据。