5.2字符串的创建、查询和修改
字符串(Strings)是Redis的基本数据结构之一。它由Key和Value两部分组成。
Redis的字符串可以简单地类比为Python的变量。其中,Key相当于变量名,Value相当于变量值。
5.2.1 使用redis-cli实现
本小节将在终端中使用redis-cli连接Redis,查看当前有哪些Key,结果如图5-8所示。
图5-8 使用redis-cli连接Redis并查看当前数据
1.创建字符串
往Redis中添加一条字符串的命令为:
set key value
其中:
● key可以是数字、大小写字母、下画线或者中文。
● value可以是任意内容。
往Redis中添加一个字符串,使用的关键字为set。假设它的Key为“give_me_a_world”,它的值为“OK”,那么可以使用如下命令来实现:
set give_me_a_world OK
2.查询字符串
添加完成后,可以查看Redis里面有多少Key,结果如图5-9所示。
图5-9 字符串已经被成功添加到了Redis中
提示:
虽然Key可以使用中文,但是不建议使用。因为在列出Redis当前所有Key时,中文内容会变得难以阅读,如图5-10所示。
其中的“\xe4\xb8\xad\xe6\x96\x87”对应的就是“中文”这两个汉字。
图5-10 列出Redis所有Key时,中文会变成Unicode码
3.读取字符串
(1)从Redis中读取一个字符串的值。
使用的关键字为“get”。例如:
get give_me_a_world
运行效果如图5-11所示。
(2)从Redis中读取一个字符串。
命令格式为:
get key
如果获取一个不存在的Key,则会返回(nil),如图5-12所示。
图5-11 从Redis中获取一个字符串的值
图5-12 获取一个不存在的Key
如果Redis中有中文Key,则也可以获取中文Key对应的值,如图5-13所示。
图5-13 获取中文Key
提示:
从图5-13中可以看出:如果字符串的值为中文,那么在redis-cli里获取出的中文值是难以阅读的;但中文Key里的内容无论是英文还是数字,在redis-cli里获取后都可以正常显示。
可能有读者会认为,从“set”和“get”的用法来看,Redis 的字符串真是太简单了。但实际上,在Redis中操作字符串有24个不同的命令,每一个命令还有多种不同的参数。“set”与“get”只是其中的两个。由于篇幅所限,本书会挑选其中几条重要的命令来讲解。
4.修改Key里面的值
如果要修改一个Key里面的值,则使用以下命令即可(如图5-14所示):
set key 新的值
修改Key里面的值有以下几种情况:
(1)如果Redis不存在这个Key,那么使用“set”命令可以创建它;如果Redis里面已经有了这个Key,那么使用“set”命令可以用新的值覆盖旧的值。
提示:
如果不希望set命令覆盖旧的值怎么办呢?可以使用一个参数“NX”。如果一个Key已经存在于Redis中,那么就不覆盖,直接放弃操作。命令格式如下,运行效果如图5-15所示。
set key value NX
图5-14 set命令直接覆盖原有值
图5-15 如果Key已经存在,就放弃操作
(2)如果需要做的修改是给字符串的末尾加上其他字符串,则可以不使用“set”命令,而改用“append”命令。
格式为:
append key value
运行效果如图5-16所示。
(3)如果值的内容有空格,那么直接添加值就会报错。为防止报错,则需要使用双引号把有空格的内容包起来,格式如下:
set key "word1 word2 word3"
运行效果如图5-17所示。
图5-16 使用append命令追加字符
图5-17 使用双引号“包”住有空格的值
字符串作为一个数据结构,虽然名为“字符串”(Strings),但它是可以保存数字的,如图5-18所示。
图5-18 字符串也可以保存数字
(4)如果需要这个值加减某个数该怎么办呢?这时可以使用命令“incr”“decr”“incrby”或“decrby”。
● Incr会让Key里的数字增加1,具体语法如下:
incr key
● decr会让Key里的数字减少1,具体语法如下:
decr key
● incrby会让Key里的数字增加n,具体语法如下:
incrby key n
● decrby会让Key里的数字减少n,具体语法如下:
decrby key n
运行效果如图5-19所示。
图5-19 对值为数字的字符串进行增减操作
从图5-19中也可以看到,执行完这些命令后,Redis直接返回的就是结果,这个结果与“get”获得的结果是一样的。
5.2.2 使用Python实现
Python操作Redis的第三方库叫作“redis-py”。要使用它,需要首先通过Python的“pip”命令来安装它:
python3 -m pip install redis
提示:
由于Python有Python 2和Python 3两个版本,并且两个版本可以同时存在于一台电脑中,所以相应地pip也有pip 2和pip 3。
由于系统默认会把先安装的那个Python的版本号去掉,所以:
● 如果先安装的是Python 2,则使用命令“pip install ×××”会把第三方库安装到Python 2中。
● 如果先安装的是Python 3,则使用命令“pip install ×××”会把第三方库安装到Python 3中。
为了防止出现这样的误会,这里统一使用的是命令“python3 -m pip install ×××”这种方式,这样一定会把第三方库安装到Python 3的环境下,从而避免混淆。本书安装的所有第三方库都会使用这种正确的写法。
安装过程如图5-20所示。
图5-20 为Python安装redis-py
安装完成后,打开Python的交互环境测试安装结果,尝试导入Redis。如果系统不报错(如图5-21所示),则说明导入成功,导入成功也就意味着安装成功。
图5-21 导入Redis不报错则说明安装成功
导入成功后,创建一个Redis的客户链接:
>>> import redis
>>> client = redis.Redis()
后面的所有操作都使用这个“client”对象来进行。
redis-py操作字符串使用的关键字与redis-cli使用的关键字完全相同,唯一不同的是参数的组织方式。
首先介绍如何列出Redis中的所有Key。代码如下:
代码5-1 在Python中列出Redis中的所有Key
运行效果如图5-22所示。
图5-22 列出所有的Key
“client.keys()”返回的是一个列表,列表里是bytes型Key。使用for循环把这个列表展开后,将Key转换为Python中的字符串型数据,包括中文在内的Key就可以正常显示了。
1.创建字符串
添加一个字符串使用的是“client.set()”,格式如下:
>>> client.set('key', 'value')
获取一个字符串的值使用的是“client.get()”,格式如下:
>>> client.get('key')
运行效果如图5-23所示。
图5-23 使用Python添加获取字符串
提示:
不论是Python的字符串还是数字,一旦进了Redis再出来就会变成bytes型的数据,因此需要注意做好格式转换。
在redis-cli里,set命令有一个nx参数,在Python中也可以使用:
>>> client.set('key', 'value', nx=True)
如果Key已经存在了,则不会覆盖原有数据,如图5-24所示。
图5-24 在Python中也可以使用nx参数
在Python中,也可以使用关键字“append”把新的字符添加到已有的字符串后面,如图5-25所示。
图5-25 在Python中使用append
redis-cli中的“incr”“decr”命令在Python中也可以正常使用,redis-cli中的“incrby”“decrby”命令在Python相当于可用,见代码5-2。
代码5-2 在Python中对字符串进行增加和减小
在Python中,“client.incr()”与“client.decr()”都可以接收两个参数:第1个参数是Key,第2个参数是数字。第2个参数可以省略,省略表示1。运行效果如图5-26所示。
图5-26 使用Python对字符串中的数字进行增减
5.2.3 字符串的应用
在工程上,Redis的字符串常用来记录简单的映射关系。
例如,有10000条用户ID和用户名,ID和用户名的对应关系如下:
出于某些原因,系统需要频繁查询不同ID对应的用户名,那么就可以使用字符串来实现。此时如果查看Redis的Key,则可以看到如图5-27所示的内容。
图5-27 使用字符串保存简单的映射关系
一个ID就是一个Key,每个ID里的值就是用户名。假设要获取ID为“1000006”的用户名,则代码可以写为:
代码5-3 在Python中获取字符串的值
由于 Redis 的数据保存在内存中,所以这种查询方式的速度非常快,可以满足对查询速度要求比较高但查询逻辑简单的查询操作。
提示:
(1)字符串只应用在小量级的数据记录中。如果数据量超过百万级别,那么使用字符串来保存简单的映射关系将会浪费大量内存。此时需要使用Redis的另一种数据结构——Hash。储存相同量级的数据,Hash 结构消耗的内存只有字符串结构的1/4,但查询速度却不会比字符串差。关于Hash结构,将会在第9章讲解。
(2)如果Redis中有大量Key,那么执行“keys *”命令会对Redis性能造成短暂影响,甚至导致Redis失去响应。因此,绝对不应该在不清楚当前有多少Key的情况下冒然列出当前所有的Key。