Redis 基础 -- 字符串 String 类型 和 String 类型的常用命令

Posted CodeJiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 基础 -- 字符串 String 类型 和 String 类型的常用命令相关的知识,希望对你有一定的参考价值。

文章目录

1. 字符串 String

字符串(String)键是Redis最基本的键值对类型,这种类型的键值对会在数据库中把单独的一个键和单独的一个值关联起来,被关联的键和值既可以是普通的文字数据,也可以是图片、视频、音频、压缩文件等更为复杂的二进制数据。


1.1 SET:为字符串键设置值

语法:


在最基本的情况下,用户只需要向SET命令提供一个键和一个值就可以了:

比如通过执行以下命令,我们可以创建出一个字符串键,它的键为"number",值为"5050":


1.1.1 改变覆盖规则 NX | XX

在默认情况下,对一个已经设置了值的字符串键执行SET命令将导致键的旧值被新值覆盖

在第二条SET命令执行完毕之后,song_title键的值将从原来的"Get Wild"变为"Running to Horizon"。

从Redis 2.6.12版本开始,用户可以通过向SET命令提供可选的NX选项或者XX选项来指示SET命令是否要覆盖一个已经存在的值:

NX: 只在键不存在时执行

如果用户在执行SET命令时给定了NX选项,那么SET命令只会在键不存在的情况下执行设置操作,并返回OK表示设置成功;如果键已经存在,那么SET命令将放弃执行设置操作,并返回空值nil表示设置失败。

XX: 只在键存在时执行

如果用户在执行SET命令时给定了XX选项,那么SET命令只会在键已经存在情况下执行设置操作,并返回OK表示设置成功;如果给定的键并不存在,那么SET命令将放弃执行设置操作,并返回空值表示设置失败。


1.1.2 说明

  • 复杂度:O(1)。
  • 版本要求:不带任何可选项的SET命令从Redis 1.0.0版本开始可用;带有NX、XX等可选项的SET命令从Redis 2.6.12版本开始可用。

1.2 获取字符串键的值

用户可以使用GET命令从数据库中获取指定字符串键的值:

语法:

示例:

说明:

  • 复杂度:O(1)。

1.3 GETSET:获取旧值并设置新值

GETSET命令就像GET命令和SET命令的组合版本,GETSET首先获取字符串键目前已有的值,接着为键设置新值,最后把之前获取到的旧值返回给用户。

语法:

示例:


如果被设置的键并不存在于数据库,那么GETSET命令将返回空值作为键的旧值:

说明:

复杂度:O(1)。


1.4 MSET:一次为多个字符串键设置值

除了SET命令和GETSET命令之外,Redis还提供了MSET命令用于对字符串键进行设置。与SET命令和GETSET命令只能设置单个字符串键不同,MSET命令可以一次为多个字符串键设置值。

语法:

示例:

以下代码展示了如何使用一条MSET命令去设置message、number和homepage这3个键:

与SET命令一样,MSET命令也会在执行设置操作之后返回OK表示设置成功。此外,如果给定的字符串键已经有相关联的值,那么MSET命令也会直接使用新值去覆盖已有的旧值。

优点:

MSET命令除了可以让用户更为方便地执行多个设置操作之外,还能有效地提高程序的效率:执行多条SET命令需要客户端和服务器之间进行多次网络通信,并因此耗费大量的时间;而使用一条MSET命令去代替多条SET命令只需要一次网络通信,从而有效地减少程序执行多个设置操作时的时间。

说明:

复杂度:O(N),其中N为用户给定的字符串键数量。


1.5 MGET:一次获取多个字符串键的值

MGET命令就是一个多键版本的GET命令,MGET接受一个或多个字符串键作为参数,并返回这些字符串键的值。

语法:

示例:

以下代码展示了如何使用一条MGET命令去获取message、number和homepage这3个键的值:

与GET命令一样,MGET命令在碰到不存在的键时也会返回空值

优点:

与MSET命令类似,MGET命令也可以将执行多个获取操作所需的网络通信次数从原来的N次降低至只需一次,从而有效地提高程序的运行效率。

说明:

复杂度:O(N),其中N为用户给定的字符串键数量。


1.6 MSETNX:只在键不存在的情况下,一次为多个字符串键设置值

MSETNX命令与MSET命令一样,都可以对多个字符串键进行设置。

语法:


MSETNX与MSET的主要区别在于,MSETNX只会在所有给定键都不存在的情况下对键进行设置,而不会像MSET那样直接覆盖键已有的值:如果在给定键当中,即使有一个键已经有值了,那么MSETNX命令也会放弃对所有给定键的设置操作。MSETNX命令在成功执行设置操作时返回1,在放弃执行设置操作时则返回0。

示例:

在以下代码中,因为键k4已经存在,所以MSETNX将放弃对键k1、k2、k3和k4进行设置操作:

如果只对不存在的键k1、k2和k3进行设置,那么MSETNX可以正常地完成设置操作:

说明:

复杂度:O(N),其中N为用户给定的字符串键数量。


1.7 STRLEN:获取字符串值的字节长度

通过对字符串键执行STRLEN命令,用户可以取得字符串键存储的值的字节长度。

语法:

示例:

设置值

获取值的长度

说明:

复杂度:O(1)。


1.8 字符串值的索引

因为每个字符串都是由一系列连续的字节组成的,所以字符串中的每个字节实际上都拥有与之相对应的索引。Redis为字符串键提供了一系列索引操作命令,这些命令允许用户通过正数索引或者负数索引,对字符串值的某个字节或者某个部分进行处理,其中:

  • 字符串值的正数索引以0为开始,从字符串的开头向结尾不断递增。
  • 字符串值的负数索引以-1为开始,从字符串的结尾向开头不断递减。

下图展示了值为"hello world"的字符串,及其各个字节相对应的正数索引和负数索引。


1.9 GETRANGE:获取字符串值指定索引范围上的内容

通过使用GETRANGE命令,用户可以获取字符串值从start索引开始,直到end索引为止的所有内容。

语法:

示例:


说明:

复杂度:O(N),其中N为被返回内容的长度。


1.10 SETRANGE:对字符串值的指定索引范围进行设置

通过使用SETRANGE命令,用户可以将字符串键的值从索引index开始的部分替换为指定的新内容,被替换内容的长度取决于新内容的长度。

语法:


SETRANGE命令在执行完设置操作之后,会返回字符串值当前的长度作为结果。

示例:

我们可以通过执行以下命令,将message键的值从原来的"hello world"修改为"hello Redis":

命令的执行过程


1.10.1 自动扩展被修改的字符串

当用户给定的新内容比被替换的内容更长时,SETRANGE命令就会自动扩展被修改的字符串值,从而确保新内容可以顺利写入。

以下代码就展示了如何通过SETRANGE命令,将message键的值从原来的11字节长修改为41字节长:

SETRANGE命令扩展字符串并进行写入的过程:


1.10.2 在值里面填充空字节

SETRANGE命令除了会根据用户给定的新内容自动扩展字符串值之外,还会根据用户给定的index索引扩展字符串。

当用户给定的index索引超出字符串值的长度时,字符串值末尾直到索引index-1之间的部分将使用空字节进行填充,换句话说,这些字节的所有二进制位都会被设置为0。

示例:

对于字符串键greeting来说:

当我们执行以下命令时,SETRANGE命令会先将字符串值扩展为15个字节长,然后将"hello"末尾直到索引9之间的所有字节都填充为空字节,最后再将索引10到索引14的内容设置为"world"。

通过执行GET命令,我们可以取得greeting键在执行SETRANGE命令之后的值:

下图展示了这个扩展、填充、最后设置的过程


1.10.3 说明

复杂度:O(N),其中N为被修改内容的长度。


1.11 APPEND:追加新内容到值的末尾

通过调用APPEND命令,用户可以将给定的内容追加到字符串键已有值的末尾。

语法:

示例:

处理不存在的键:

如果用户给定的键并不存在,那么APPEND命令会先将键的值初始化为空字符串"",然后再执行追加操作,最终效果与使用SET命令为键设置值的情况类似。

说明:

复杂度:O(N),其中N为新追加内容的长度。


1.12 使用字符串键存储数字值

每当用户将一个值存储到字符串键里面的时候,Redis都会对这个值进行检测,如果这个值能够被解释为以下两种类型的其中一种,那么Redis就会把这个值当作数字来处理:

  • 第一种类型是能够使用C语言的long long int类型存储的整数,在大多数系统中,这种类型存储的都是64位长度的有符号整数,取值范围介于-9223372036854775808和9223372036854775807之间。
  • 第二种类型是能够使用C语言的long double类型存储的浮点数,在大多数系统中,这种类型存储的都是128位长度的有符号浮点数,取值范围介于3.36210314311209350626e-4932和1.18973149535723176502e+4932L之间。

下表列举了一些不同类型的值,并说明了Redis对它们的解释方式。


1.13 INCRBY、DECRBY:对整数值执行加法操作和减法操作

当字符串键存储的值能够被Redis解释为整数时,用户就可以通过INCRBY命令和DECRBY命令对被存储的整数值执行加法或减法操作。

INCRBY命令用于为整数值加上指定的整数增量,并返回键在执行加法操作之后的值。

语法:

加法:INCRBY

减法:DECRBY

示例:

以下代码展示了如何使用INCRBY命令去增加一个字符串键的值:

与INCRBY命令的作用正好相反,DECRBY命令用于为整数值减去指定的整数减量,并返回键在执行减法操作之后的值:


1.13.1 类型限制

当字符串键的值不能被Redis解释为整数时,对键执行INCRBY命令或是DECRBY命令将返回一个错误:


另外需要注意的一点是,INCRBY和DECRBY的增量和减量也必须能够被Redis解释为整数,使用其他类型的值作为增量或减量将返回一个错误:

同理也不可以用字符串作为增量。


1.3.2 处理不存在的键

当INCRBY命令或DECRBY命令遇到不存在的键时,命令会先将键的值初始化为0,然后再执行相应的加法操作或减法操作。


1.3.3 说明

复杂度:O(1)。


1.14 INCR、DECR:对整数值执行加1操作和减1操作

因为对整数值执行加1操作或减1操作的场景经常会出现,所以为了能够更方便地执行这两个操作,Redis分别提供了用于执行加1操作的INCR命令以及用于执行减1操作的DECR命令。

语法:

INCR

DECR

示例:

DECR与INCR类似,这里就不演示了。

说明:

除了增量和减量被固定为1之外,INCR命令和DECR命令的其他方面与INCRBY命令以及DECRBY命令完全相同。

复杂度:O(1)。


1.15 INCRBYFLOAT:对数字值执行浮点数加法操作

NCRBYFLOAT命令可以把一个浮点数增量加到字符串键存储的数字值上面,并返回键在执行加法操作之后的数字值作为命令的返回值。

语法:

示例:

以下代码展示了如何使用INCRBYFLOAT命令去增加一个浮点数的值:


1.15.1 处理不存在的键

INCRBYFLOAT命令在遇到不存在的键时,会先将键的值初始化为0,然后再执行相应的加法操作。


1.15.2 使用INCRBYFLOAT执行浮点数减法操作

用户只能通过给INCRBYFLOAT命令传入负数增量来执行浮点数减法操作。

示例:


1.15.3 INCRBYFLOAT与整数值

INCRBYFLOAT命令对于类型限制的要求比INCRBY命令和INCR命令要宽松得多:

  • INCRBYFLOAT命令既可用于浮点数值,也可以用于整数值。
  • INCRBYFLOAT命令的增量既可以是浮点数,也可以是整数。
  • 当INCRBYFLOAT命令的执行结果可以表示为整数时,命令的执行结果将以整数形式存储。

示例:


1.15.4 小数位长度限制

虽然Redis并不限制字符串键存储的浮点数的小数位长度,但是在使用INCRBYFLOAT命令处理浮点数的时候,命令最多只会保留计算结果小数点后的18位数字,超过这个范围的小数将被截断。

示例:


1.15.5 说明

复杂度:O(1)。


1.16 重点回顾

  • Redis的字符串键可以把单独的一个键和单独的一个值在数据库中关联起来,并且这个键和值既可以存储文字数据,又可以存储二进制数据。
  • SET命令在默认情况下会直接覆盖字符串键已有的值,如果我们只想在键不存在的情况下为它设置值,那么可以使用带有NX选项的SET命令;相反,如果我们只想在键已经存在的情况下为它设置新值,那么可以使用带有XX选项的SET命令。
  • 使用MSET、MSETNX以及MGET命令可以有效地减少程序的网络通信次数,从而提升程序的执行效率。
  • Redis用户可以通过制定命名格式来提升Redis数据的可读性并避免键名冲突。
  • 字符串值的正数索引以0为开始,从字符串的开头向结尾不断递增;字符串值的负数索引以-1为开始,从字符串的结尾向开头不断递减。
  • GETRANGE key start end命令接受的是闭区间索引范围,位于start索引和end索引上的值也会被包含在命令返回的内容当中。
  • SETRANGE命令在需要时会自动对字符串值进行扩展,并使用空字节填充新扩展空间中没有内容的部分。
  • APPEND命令在键不存在时执行设置操作,在键存在时执行追加操作。Redis会把能够被表示为long long int类型的整数以及能够被表示为longdouble类型的浮点数当作数字来处理。


以上是关于Redis 基础 -- 字符串 String 类型 和 String 类型的常用命令的主要内容,如果未能解决你的问题,请参考以下文章

redis入门基础学习--基本数据类型[String]

Redis数据类型大全:“5种基础”数据类型+“3种特殊”数据类型

兄弟连学python---Redis基础知识

Redis学习基础二

Redis 基础 -- 字符串 String 类型 和 String 类型的常用命令

Redis数据类型