Python 操作 Redis 数据库

Python 操作 Redis 数据库

1. 简介

Redis 是是一个高性能的 key-value 数据库。Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的 key-value 类型的数据,同时还提供 list、set、zset、hash 等数据结构的存储。

Python 程序要访问 Redis,需要使用第三方模块 redis。

2. 安装模块 redis

redis 是 python 访问 Redis 数据库的模块。首先检查是否已经安装了 redis 模块,在 python 交互模式下 import redis,如下所示:

>>> import redis
Traceback (most recent call last):
  File <stdin>, line 1, in <module>ModuleNotFoundError: No module named 'redis'

如果出现错误:ModuleNotFoundError,则表示还没有安装 redis,使用 pip3 install mysql 安装 redis,如下所示:

$ pip3 install redis
Collecting redis...
Installing collected packages: redis
Successfully installed redis-3.5.3

3. 连接 redis 数据库

使用 redis.Redis() 方法连接 redis 数据库,示例如下:

>>> import redis>>> db = redis.Redis(host='localhost')>>> db.set('name', 'ZhangSan')True>>> db.get('name')b'ZhangSan'
  • 在第 1 行,引入 redis 模块

  • 在第 2 行,使用 redis.Redis() 方法连接 redis 数据库,返回一个数据库连接对象 db

  • 在第 3 行,设置键 ‘name’ 的值为 ‘ZhangSan’

  • 在第 5 行,获取键 ‘name’ 的值

  • 在第 6 行,redis 数据库返回的是字节对象 b’ZhangSan’,而不是字符串 ‘ZhangSan’

在默认情况下,redis 返回的结果是字节对象,通过设定参数 decode_responses=True 使 redis 返回字符串。示例如下:

>>> import redis>>> db = redis.Redis(host='localhost', decode_responses=True)>>> db.set('name', 'ZhangSan')True>>> db.get('name')'ZhangSan'
  • 在第 2 行,使用 decode_responses=True 的方式连接 redis 数据库

  • 在第 6 行,redis 数据库返回的是字符串 ‘ZhangSan’,而不是字节对象 b’ZhangSan’

在接下来的小节中,我们使用 decode_responses=True 的方式连接 redis 数据库,通过数据库连接对象 db 向 redis 数据库发送命令。以上连接 redis 数据库的代码将不再重复。

4. 根据键访问

4.1 设置和获取一个键

>>> db.set('name', 'imooc')True>>> db.get('name')'imooc'
  • 在第 1 行,设置键 ‘name’ 的值为 ‘imooc’

  • 在第 3 行,获取键 ‘name’ 的值

4.2 设置和获取多个键

>>> db.mset({'name': 'ZhangSan', 'age': })True>>> db.mget('name', 'age')['ZhangSan', '30']>>> db.mget(['name', 'age'])['ZhangSan', '30']
  • 在第 1 行,设置两个键

    • 设置键 ‘name’ 的值为 ‘ZhangSan’

    • 设置键 ‘age’ 的值为 30

  • 在第 3 行,获取两个键的值

    • mget 返回一个记录了两个键值的数组

  • 在第 5 行,获取两个键的值的另一种调用方式

4.2 删除键

>>> db.set('name', 'ZhangSan')>>> db.get('name')'ZhangSan'>>> db.delete('name')>>> db.get('name')>>> db.get('name') == NoneTrue
  • 在第 1 行,设置键 ‘name’ 的值为 ‘ZhangSan’

  • 在第 4 行,使用 delete() 方法删除键 ‘name’

  • 删除键 ‘name’ 后,db.get(‘name’) 返回 None

5. 访问字符串

5.1 获取字符串的长度

>>> db.set('name', 'www.imooc.com')True>>> db.strlen('name')
  • 在第 1 行,设置键 ‘name’ 的值为字符串 ‘www.imooc.com

  • 在第 3 行,通过 strlen() 方法获取键 ‘name’ 的值的长度

5.2 获取字符串的子串

>>> db.getrange('name', , )'www'>>> db.getrange('name', , )'imooc'>>> db.getrange('name', , )'com'>>>
  • 在第 1 行,获取字符串中范围为 [0, 2] 的子串,即 ‘www’

  • 在第 3 行,获取字符串中范围为 [4, 8] 的子串,即 ‘imooc’

  • 在第 5 行,获取字符串中范围为 [10, 12] 的子串,即 ‘com’

5.3 设置字符串的子串

>>> db.setrange('name', , 'IMOOC')>>> db.get('name')'www.IMOOC.com'
  • 在第 1 行,将字符串中从 4 开始的子串 ‘imooc’,替换为 ‘IMOOC’

6. 访问列表

6.1 创建列表

>>> db.rpush('url', 'www')>>> db.rpush('url', 'imooc')>>> db.rpush('url', 'com')
  • 方法 rpush(list, value) 将值 value 添加到列表 list 的尾部

    • 如果列表 list 不存在,会创建一个空列表

  • 在第 1 行,创建一个列表 url,将字符串 ‘www’ 添加到列表的尾部

  • 在第 2 行,将字符串 ‘imooc’ 添加到列表的尾部

  • 在第 3 行,将字符串 ‘com’ 添加到列表的尾部

6.2 访问列表

>>> db.llen('url')>>> db.lindex('url', )'www'>>> db.lindex('url', )'imooc'>>> db.lindex('url', )'com'
  • 在第 1 行,方法 llen(‘url’) 返回列表 url 的长度

  • 在第 3 行,llindex(‘url’, 0) 返回列表 url 中第 0 项的数据

  • 在第 5 行,llindex(‘url’, 1) 返回列表 url 中第 1 项的数据

  • 在第 7 行,llindex(‘url’, 2) 返回列表 url 中第 2 项的数据

6.3 获取指定范围的元素

>>> db.lrange('url', , )['www', 'imooc']>>> db.lrange('url', , )['www', 'imooc', 'com']
  • lrange(start, stop) 返回列表中指定区间 [start, stop] 内的元素

  • 在第 1 行,获取列表 url 中范围 [0, 1] 内的 2 项元素

  • 在第 3 行,获取列表 url 中范围 [0, 2] 内的 3 项元素

6.4 在列表中插入数据

>>> db.lrange('url', , )['www', 'imooc', 'com']>>> db.linsert('url', 'after', 'www', '.')>>> db.linsert('url', 'before', 'com', '.')>>> db.lrange('url', , )['www', '.', 'imooc', '.', 'com']
  • 在第 3 行,在数据项 ‘www’ 的后面,插入数据项 ‘.’

  • 在第 5 行,在数据项 ‘com’ 的前面,插入数据项 ‘.’

  • 在第 8 行,结果显示

    • 在 ‘www’ 和 ‘imooc’ 之间增加了一项 ‘.’

    • 在 ‘imooc’ 和 ‘com’ 之间增加了一项 ‘.’

6.5 修改列表

>>> db.lindex('url', )'imooc'>>> db.lset('url', , 'IMOOC')True>>> db.lindex('url', )'IMOOC'
  • 在第 1 行,显示列表 ‘url’ 的第 1 项内容为 ‘imooc’

  • 在第 3 行,将列表 ‘url’ 的第 1 项内容修改为 ‘IMOOC’

  • 在第 5 行,显示列表 ‘url’ 的第 1 项内容为 ‘IMOOC’

6.6 将列表作为堆栈

>>> db.rpush('stack', 'www')>>> db.rpush('stack', 'imooc')>>> db.rpush('stack', 'com')>>> db.llen('stack')
  • 方法 rpush(list, value) 将数据增加到列表 list 尾部,相当于堆栈的 push 操作

  • 将 3 个字符串 ‘www’、‘imooc’、‘com’ 依次压入到堆栈 stack 中

  • 此时堆栈 stack 的长度为 3

>>> db.rpop('stack')'com'>>> db.rpop('stack')'imooc'>>> db.rpop('stack')'www'>>> db.llen('stack')
  • 方法 rpop(list) 将数据从列表 list 尾部删除,相当于堆栈的 pop 操作

  • 从堆栈 stack 中依次弹出 ‘com’、‘imooc’、‘www’

  • 此时堆栈 stack 的长度为 0

7. 访问集合

7.1 创建集合

>>> db.sadd('set', 'a')>>> db.sadd('set', 'b')>>> db.sadd('set', 'c')
  • 方法 sadd(set, value) 向集合 set 中添加元素 value

    • 如果集合 set 不存在,则创建一个集合

  • 在第 1 行,向集合 ‘set’ 添加元素 ‘a’

  • 在第 3 行,向集合 ‘set’ 添加元素 ‘b’

  • 在第 5 行,向集合 ‘set’ 添加元素 ‘c’

7.2 获取集合的成员

>>> db.scard('set')>>> db.smembers('set'){'b', 'c', 'a'}
  • 在第 1 行,使用方法 scard(‘set’) 获取集合的元素的数量

  • 在第 3 行,使用方法 smembers(‘set’) 获取集合的所有元素

>>> db.sismember('set', 'b')True>>> db.sismember('set', 'd')False
  • 在第 1 行,使用方法 sismember(‘set’, ‘b’) 检查集合 ‘set’ 是否包含 ‘b’

  • 在第 3 行,使用方法 sismember(‘set’, ‘d’) 检查集合 ‘set’ 是否包含 ‘d’

7.3 求集合的交、并、差

>>> db.sadd('set2', 'b')>>> db.sadd('set2', 'c')>>> db.sadd('set2', 'd')
  • 创建集合 ‘set2’,向集合 ‘set2’ 中添加元素 ‘b’、‘c’、‘d’

>>> db.smembers('set'){'a', 'b', 'c'}>>> db.smembers('set2'){'b', 'd', 'c'}
  • 显示集合 ‘set’ 与 集合 ‘set2’ 包含的成员

>>> db.sinter('set', 'set2'){'b', 'c'}>>> db.sunion('set', 'set2'){'a', 'b', 'd', 'c'}
  • db.sinter(‘set’, ‘set2’) 求取集合的交集

  • db.sunion(‘set’, ‘set2’) 求取集合的并集

>>> db.sdiff('set', 'set2'){'a'}>>> db.sdiff('set2', 'set'){'d'}
  • db.sdiff(‘set’, ‘set2’) 求取集合的差集

    • 在 ‘set’ 中出现,在 ‘set2’ 中没有出现的元素构成的集合

  • db.sdiff(‘set2’, ‘set’) 求取集合的差集

    • 在 ‘set2’ 中出现,在 ‘set’ 中没有出现的元素构成的集合

8. 访问哈希

8.1 创建哈希表

>>> db.hset('person', 'name', 'ZhangSan')>>> db.hset('person', 'age', )
  • 方法 hset(hash_table, key, value),向哈希表 hash_table 增加一组键值对,键为 key、值为 value

    • 如果哈希表 hash_table 不存在,则创建一个新的哈希表

  • 创建一个哈希表 person,描述一个人,包括两项属性:name 和 age

  • 在第 1 行,为哈希表 person 增加一组键值对:键为 ‘name’、值为 ‘ZhangSan’

  • 在第 3 行,为哈希表 person 增加一组键值对:键为 ‘age’、值为 20

>>> db.hlen('person')
  • 方法 hlen(hash_table) 获取 hash_table 中键值对的数目

8.2 访问哈希表

>>> db.hget('person', 'name')'ZhangSan'>>> db.hget('person', 'age')'20'
  • 方法 hget(hash_table, key) 获取哈希表 hash_table 中键为 key 对应的值

  • 在第 1 行,获取哈希表 ‘person’ 中键为 ‘name’ 的值

  • 在第 3 行,获取哈希表 ‘person’ 中键为 ‘age’ 的值

>>> db.hexists('person', 'name')True>>> db.hexists('person', 'gender')False
  • 方法 hexists(hash_table, key) 返回哈希表 hash_table 是否包含键 key

  • 在第 1 行,获取哈希表 ‘person’ 是否包含 ‘name’

  • 在第 3 行,获取哈希表 ‘person’ 是否包含 ‘gender’

8.3 获取所有的键和值

>>> db.hkeys('person')
['name', 'age']
>>> db.hvals('person')
['ZhangSan', '20']
>>> db.hgetall('person')
{'name': 'ZhangSan', 'age': '20'}
  • 方法 hkeys(hash_table) 返回 hash_table 中所有的键

  • 方法 hvals(hash_table) 返回 hash_table 中所有的值

  • 方法 hgetall(hash_table) 返回一个字典,描述 hash_table 中所有的键和值

8.4 遍历哈希表

>>> keys = db.hkeys('person')>>> for key in keys:...     val = db.hget('person', key)...     print('%s:%s' % (key, val))...name:ZhangSan
age:
  • 在第 1 行,通过 hkeys() 方法获取所有的键

  • 在第 2 行,使用 for 循环遍历所有的键

  • 在第 3 行,使用 hget() 方法获取指定键对应的值

>>> dict = db.hgetall('person')>>> for key,val in dict.items():...     print('%s:%s' % (key, val))...name:ZhangSan
age:
  • 在第 1 行,通过 hgetall() 方法获取所有的键值对,该方法返回一个字典

  • 遍历 hgetall() 返回的字典

8.5 增加键和删除键

>>> db.hset('person', 'gender', 'female')>>> db.hgetall('person'){'name': 'ZhangSan', 'age': '20', 'gender': 'female'}>>> db.hdel('person', 'gender')>>> db.hgetall('person'){'name': 'ZhangSan', 'age': '20'}
  • 在第 1 行,为哈希表 ‘person’ 增加一个键 ‘gender’,值为 ‘female’

  • 在第 3 行,使用方法 hgetall(‘person’) 显示哈希表 ‘person’ 的键值对

    • 已经增加了一个键 ‘gender’

  • 在第 5 行,使用方法 hdel(‘person’, ‘gender’) 删除哈希表 ‘person’ 中的键 ‘gender’

  • 在第 7 行,使用方法 hgetall(‘person’) 显示哈希表 ‘person’ 的键值对

    • 已经删除了键 ‘gender’