redis的使用

1. redis介绍

redis是一个key-value存储系统, 速度快, 支持丰富数据类型, 支持事务, 支持持久化, 丰富的特性...
速度快: 因为数据存在内存中, 类似于HashMap, HashMap的优势就是查找和操作的时间复杂度都是O(1)
       使用I/O多路复用, 是单进程单线程的架构, 避免了线程和进程之间切换的资源消耗.
支持丰富数据类型: 支持string, list, set, sorted set(有序集合), hash(字典)
支持事务:操作都是原子性, 所谓的原子性就是对数据的更改要么全部执行, 要么全部不执行.
支持持久化: 将数据存到硬盘中.
丰富的特性:可用于缓存, 消息, 按key设置过期时间, 过期后将会自动删除.
PS: Memcached:另一个key-value存储系统, 操作更简洁.
    只支持字符串类型数据, 不支持持久化, 数据断电丢失.
redis适合的场景:
    1 排行榜 (使用 sorted set数据类型)
    2 网站访问量, 文章访问量 
    3 缓存数据库(str 缓存接口 hash)
    4 发布订阅
    5 去重(set类型)
    6 分布式blpop (类别类型)

2. redis安装

* 1. 官方不支持Windows版本的Redis, 因此官网上不提供下载.
	 但微软开发和维护着支持win-64的Redis版本, 因此可以去下载.
     地址: https://github.com/MicrosoftArchive/redis/releases

image-20220524124736935

MSI文件是Windows Installer的数据包, 它实际上是一个数据库.
包含安装一种产品所需要的信息和在很多安装情形下安装(和卸载)程序所需的指令和数据.
* 2. 点击安装包安装(包含服务端和客户端)

GIF 2022-5-24 12-56-19

勾选 Add the Redis installation filder to the PATH environment variable. 添加到环境变量
端口 6379, 不限制使用的内存大小.

image-20220524130440280

服务端会自动添加到windows的服务中, 自动启动.
这个服务使用 redis-server 配置文件.conf 启动服务端.
* 3. 客户端连接服务端
	 redis-cli -h 地址 -p 端口 连接服务端
	 redis-cli 命令默认使用127.0.0.1  6379
* 4. 存值&取值&退出
     存值: set key 
     取值: get key
     退出: exit

image-20220524131016467

3. redis桌面管理器

该工具为您提供了一个易于使用的GUI, 可以访问您的Redis数据库并执行一些基本操作:
将键视为树, CRUD键, 通过shell执行命令.
官网: https://redisdesktop.com/download
* 1. 安装步骤

GIF 2022-5-24 13-24-44

* 2. 连接服务端

2022-05-24_00889

* 3. 基操, 嘿嘿

2022-05-24_00891

4. Python连接redis

* 1. 安装redis模块
	 pip install redis
* 2. 简单使用
from redis import Redis

# host = "localhost", port = 6379,
conn = Redis()  # 生成连接对象, 连接一次

# (str, bytes) 值都会被转换为bytes类型
conn.set('age', 18)  # 存值
res = conn.get('age')  # 取值

print(res)  # b'18'

decode_response=True 参数对取出的值进行解码.
from redis import Redis

# decode_response=True 对取出的值进行解码.
conn = Redis(decode_responses=True)  # 生成连接对象, 连接一次

# (str, bytes) 值都会被转换为bytes类型
conn.set('age', 18)  # 存值
res = conn.get('age')  # 取值

print(res)  # 18

ps: QPS: 指每秒查询率。
redis的QPS 10, 实际测试在6万多.

5. 连接池

正确访问操作一次连接一次, 如果项目中建立很多连接, 会影响redis的性能.
连接池: (一次连接就会使用一个连接对象)
在项目运行时先创建固定个数的连接对象, 放进连接池(列表).
需要操作redis时, 从连接池中随机拿一个连接对象, 操作完之后再放进连接池.
连接池是一个单例模式.
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.
当你希望在整个系统中, 某个类只能出现一个实例时, 单例对象就能派上用场.
模块实现方式:
python 的模块就是天然的单例模式, 因为模块在第一次导入时, 会生成 .pyc 文件.
当第二次导入时, 就会直接加载 .pyc 文件, 而不会再次执行模块代码.
因此, 我们只需把相关的函数和数据定义在一个模块中, 就可以获得一个单例对象了.
* 1. connection_pool.py 中创建连接池
# 导入redis
import redis


# 创建连接池 max_connections, 设置连接池的数量
POOL = redis.ConnectionPool(max_connections=100)
* 2. test_redis.py 中使用连接池的对象
# 导入连接池
from connection_pool import POOL

import redis
# 从连接池中获取到一个连接对象
conn = redis.Redis(connection_pool=POOL)
# 通过连接对象操作redis
print(conn.get('name'))

6. 字符串类型使用

set 没有值则创建值, 值存在则修改值.
set(key, value, ex, px, nx, xx)
key: 
value: 
ex: 过期时间()
px: 过期时间(毫秒)
nx: 设置为True, 当key不存在的时候, set操作才会生效. (新建增的操作)
xx: 设置为True, 当key存在的时候, set操作才会生效. (修改值的操作)
6.1 存值取值
set(key, value) 设置值
get(key) 取值
getset(key, value) 先取值在刷新值
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# 存值
conn.set('k1', 1)

# 取值在刷新值
res = conn.getset('k1', 2)
print(res)  # b'1'

# 取值
print(conn.get('k1'))  # b'2'
6.1 过期时间
set('key', 'value', ex) ==> setex('key', 'value', '过期时间, 秒') 
set('key', 'value', px) ==> psetex('key', '过期时间, 毫秒', 'value') 
from connection_pool import POOL
import time
import redis

conn = redis.Redis(connection_pool=POOL)

# 设置3秒过去
conn.set('k1', 'v1', 3)
res = conn.get('k1')
print(res)  # b'v1'

# 延时4秒
time.sleep(4)
res = conn.get('k1')
print(res)  # None
6.2 写入限制
set('key', 'value', nx) ==> setnx('key', 'value') 
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# set没有写入
conn.set('k1', 'v1')
res = conn.get('k1')
print(res)  # b'v1'

# 写入限制, 键已经存在, set操作失效
conn.set('k1', 'v2', nx=True)
res = conn.get('k1')
print(res)  # b'v1'

6.3 修改限制
set('key', 'value', xx) ==> setxx('key', 'value') 
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

res = conn.get('k4')  # None
print(res)  # None

# 限制修改, 当key存在才能修改
conn.set('k4', 'v4', xx=True)
res = conn.get('k4') 
print(res)  # None
6.4 批量操作
批量设置
mset({'k1': 'v1', 'k2': 'v2'})

批量取值
mget('k1', 'k2')

批量设置并取值
mget({'k1': 'v1', 'k2': 'v2'})  
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# 批量插值
conn.mset({'k1': 'v1', 'k2': 'v2'})
# 批量获取
print(conn.mget('k1', 'k2'))  # [b'v1', b'v2']

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# 批量设置并取值
print(conn.mget({'k1': 'v1', 'k2': 'v2'}))  # [b'v1', b'v2']

6.5 区间取值
getrange(key, start, end) 区间取值, 前比后闭区间, 顾前顾后.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.set('k1', 123)

print(conn.getrange('k1', 0, 0))  # b'1'
print(conn.getrange('k1', 0, 1))  # b'12'
print(conn.getrange('k1', 0, 2))  # b'123'

6.6 替换
一个汉字占三位.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.set('k1', 123)

conn.setrange('k1', 1, 789)  # 设置一个游标, 从这个游标开始切换后面所有的值

print(conn.get('k1'))

6.7 bit操作
value的二进制表示值操作
修改位: setbit(key, , 1/0) (值只能是0/1)
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# goo 的二进制为 01100110 01101111 01101111
conn.set('str1', 'goo')
# 修改为 01101111 01101111 01101111
conn.setbit('str1', 4, 1)  # 正数第5位改为1, 从0开始
conn.setbit('str1', 7, 1)  # 正数第8位改为1, 从0开始

print(conn.get('str1'))  # b'ooo'

获取位: getbit(key, )
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# goo 的二进制为 01100110 01101111 01101111
conn.set('str1', 'goo')
print(conn.getbit('str1', 0))  # 0
print(conn.getbit('str1', 1))  # 1

统计位: bitcount(key, strat, end) 获取值对应值的二进制数1的个数
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# goo 的二进制为 01100110 01101111 01101111
print(conn.bitcount('str1'))  # 17

print(conn.bitcount('str1', 0, 0))  # 5   0, 0 第一个字符对应的二进制
print(conn.bitcount('str1', 0, 1))  # 11  0, 1 第一个第二个字符对应的二进制

bitop (operation, dest, *keys)
参数: 
operation, AND(), OR(), NOT(, key只能有1), XOR(异或)
dest 新的redis的key
*key 需要查询的key, 可以是多个key.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# o 的二进制为   01101111

conn.mset({'k1': 'o', 'k2': 'o'})
print(conn.mget('k1', 'k2'))  # [b'o', b'o']

conn.bitop('AND', 'k3', 'k1', 'k2')  # AND 一一得一 零零得零

print(conn.get('k3'))  # b'o'

strlen(key)  返回value的字节格式, 一个汉字三个字节.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# o 的二进制为   01101111

conn.set('k1', '你好')
print(conn.strlen('k1'))  # 6

6.8 自增/自减
incr(self, key, amount=1) ==> incrby() 调用一次计数加1, amount可以设置, 
decr(self, key) 调用一次计数减1
incrbyfloat(self, name, amount=1.0) 当可以没有值时, key = amount, 否则自增.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# o 的二进制为   01101111

conn.set('k1', 0)
conn.incr('k1')  # 计算+1
conn.incr('k1')  # 计算+1
conn.incr('k1')  # 计算+1
print(conn.get('k1'))  # b'3'

conn.decr('k1')
print(conn.get('k1'))  # b'2'

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# o 的二进制为   01101111

conn.set('k1', 0)

conn.incr('k1', 2)

print(conn.get('k1'))  # b'2'

conn.incr('k1', -2)

print(conn.get('k1'))  # b'0'

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)


conn.incrbyfloat('k1')
print(conn.get('k1'))  # b'1'

6.9 追加
append(key, value) 在key对应的值后面追加内容
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.set('k1', 'hello')
conn.append('k1', ' word!')
print(conn.get('k1'))  # b'hello word!'

7. hash类型操作

hset(name, key, value) 存值
hsetnx(name, key, value)  name对应的hash的key不存在时则创建.
hget(name, key) 取值
name: redis的name
key hash的key
value hash的value
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.hset('n1', 'k1', 'v1')
print(conn.hget('n1', 'k1'))  # b'v1'
7.1 批量设置
hmset(name,{key1: value1, key2: value2}) 存多个值
hgset(name, k1, k2) / hgset(name, [k1, k2]) 去多个值
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2'})
print(conn.hmget('n1', 'k1', 'k2'))  # [b'v1', b'v2']
print(conn.hmget('n1', ['k1', 'k2']))  # [b'v1', b'v2']
7.2 查询所有
hgetall(name) 获取name对应的hash所有键值对.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2'})
print(conn.hgetall('n1'))  # {b'k1': b'v1', b'k2': b'v2'}


7.3 获取个数
hlen(name)  获取name对应hash的所有键值对个数.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2'})
print(conn.hlen('n1'))  # 2

7.4 获取所有键/值
hkeys(name)  获取name对应的hash所有的键
hvals(name)  获取name对应的hash所有的值
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2'})
print(conn.hkeys('n1'))  # [b'k1', b'k2']

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2'})
print(conn.hvals('n1'))  # [b'v1', b'v2']

7.5 判断键是否存在
hexists(name, key)  判断hash中是否存在某个键
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2'})
print(conn.hexists('n1', 'k1'))  # True

7.6 删除键
hdel(name, *keys)  将指定的key从hash中删除.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2'})
print(conn.hdel('n1', 'k1'))  # 1
print(conn.hgetall('n1'))  # {b'k2': b'v2'}

7.7 自增
hincrby(namen, key, amount=1)  自增
hincrbyfloat(namen, key, amount=1.0)
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hset('n1', 'k1', 0)
print(conn.hincrby('n1', 'k1'))  # 1

7.8 迭代取值
hscan(name, cursor=0, match=None, count=None)
增量式迭代获取, 可以实现切片获取数据, 并非一次性将全部取出, 全局取出数据太大会撑爆内存.
对数据量大的数据非常有用.
name: redis的name
cursor: 游标(基于游标批量获取数据)
match: 匹配指定key, 默认为None, 表示所有的Key
count: 每次分片最少获取格式, 默认None表示采用Redis的默认分片个数.

hscan_iter(name, match=None, count=None)
利用yield封装hscan创建生成器, 实现分批去redis中获取数据.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4', })
print(conn.hscan('n1'))  # (0, {b'k2': b'v2', b'k1': b'v1', b'k3': b'v3', b'k4': b'v4'})

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead. 弃用警告
conn.hmset('n1', {'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4', })

# 取数据量大的值, 不建议使用hgetall, 建议使用hscan_iter
# 一次性先取一部分, 做成生成器, 反复如此.
res = conn.hscan_iter('n1')
print(res)  # <generator object ScanCommands.hscan_iter at 0x000001E155FD1040>

for i in res:
    print(i)
"""
(b'k2', b'v2')
(b'k1', b'v1')
(b'k3', b'v3')
(b'k4', b'v4')
"""
7.9 其他
smove(rec, dstm value) 将某个成员从一个集合移动动到另一个集合
spop(name)  从集合的右侧(尾部)弹出一个成员, 并将其放回.
srandmenber(name, numbers) 从nane对应的集合移除numbers指定个数的元素
...

8. 列表操作

8.1 存取值
lpush(name, *values)  从左侧插值 后写的数据 ---> 先写的数据
rpush(name, *values)  从右侧插值 先写的数据 <--- 后写的数据

name存在才能写入
rpushx(name, values)  
lpushx(name, values)

lrange 获取list指定索引区间的数据
lrange(name, start, end)
name: 列表名称
start: 开始的索引值
end: 结束的索引值
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

res = conn.lpush('list1', 1, 2, 3, 4, 5)
print(res)  # 5 插入的数据量

print(conn.lrange('list1', 0, -1))  # [b'5', b'4', b'3', b'2', b'1']

image-20220525153108031

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

res = conn.rpush('list2', 1, 2, 3, 4, 5)
print(res)  # 5 list2的数据量

print(conn.lrange('list2', 0, -1))  # [b'1', b'2', b'3', b'4', b'5']

image-20220525153223727

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

res1 = conn.rpushx('list3', 1, )
res2 = conn.lpushx('list4', 1, )
print(res1)  # 0 list3的数据量
print(res2)  # 0 list3的数据量

8.2 统计长度
llen(name) 统计name对应的列表的长度.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list5', 1, 2, 3)
res = conn.llen('list5')

print(res)  # 3 list5长度

8.3 插入值
linsert(name, where, refvalue, value)
name: redis的name
where: BEFORE  AFTER (大小写都可以, before .. after在..)
refvalue: 游标值, : 它在前后插入数据(如果有多个游标值, 以找打的第一个为准)
value: 要插入的数据
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list6', 1, 2, 3)
# 游标是值, 在3的前面插入a, 在3d的后面插入b
conn.linsert('list6', 'BEFORE', 3, 'a')
conn.linsert('list6', 'AFTER', 3, 'b')

print(conn.lrange('list6', 0, -1))  # [b'a', b'3', b'b', b'2', b'1']

image-20220525162530643

8.4 依据索引设置值
lset(name, index, value) index从0开始
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list8', 1, 2, 3)
res1 = conn.lset('list8', 2, 'a')

image-20220525163652039

8.5 弹出值
lpop(name)  左弹
rpop(name)  右弹

rpoplpush(src, des) 从一个列表取出最右边的的元素, 同时将其添加到另一个列表的最左边.

src 要取数据的列表name
dst 要添加数据的列表name


blpop(name, timeout) 
brpop(name, timeout) 
timeout 超时时间, 超时后还没值, 返回None. timeout=0表示永久.

brpoplpush(src, des, timeout)  从一个列表取出最右边的的元素, 同时将其添加到另一个列表的最左边.
值没有了就hang住等待.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list7', 1, 2, 3)
res1 = conn.rpop('list7')  # 右弹
print(res1)  # b'1'
conn.rpop('list7')
conn.rpop('list7')
print(conn.rpop('list7'))  # None

# 左弹
res2 = conn.lpop('list7')  # b'3'
print(res2)

from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# -                  4  3  2  1  0
conn.lpush('list13', 1, 2, 3, 4, 5)
print(conn.lrange('list13', 0, -1))  # [b'5', b'4', b'3', b'2', b'1']

conn.rpoplpush('list13', 'list14')
print(conn.lrange('list14', 0, -1))  # [b'1']

# test_redis.py 先运行
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list14', 1, 2, 3)

print(conn.blpop('list14'))
print(conn.blpop('list14'))
print(conn.blpop('list14'))
print(conn.blpop('list14'))  # hang在此, 可以作为消息队列, 另一个成功往列表中插值

# test_redis2.py 后运行
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list14', 4)

image-20220525173703003

8.6 删除值
lrem(name, count, value)
name: 对应的list中删除指定的值

count=0: 删除列表中所有的指定值(列表中的值可以重复)
       count=2  从前到后, 删除两个value指定的值
       count=-2 从后向前, 删除两个value指定的值	
value: 要删除的值
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list10', 1, 2, 3, 4, 5)
print(conn.lrange('list10', 0, -1))  # [b'5', b'4', b'3', b'2', b'1']

conn.lrem('list10', count=0, value=1)
print(conn.lrange('list10', 0, -1))  # [b'5', b'4', b'3', b'2']

8.7 索引取值
lindex(name, index)  依据索引取值
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

conn.lpush('list11', 1, 2, 3, 4, 5)
print(conn.lindex('list11', 0))  # b'5'

8.8 居间移除
ltrim(name, start, end) 移除区间以外的值
start: 索引的起始位置
end: 索引结束位置(大于列表长度, 则代表不异常任何)
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# -                  4  3  2  1  0
conn.lpush('list12', 1, 2, 3, 4, 5)
print(conn.lrange('list12', 0, -1))

conn.ltrim('list12', 0, 0)
print(conn.lrange('list12', 0, -1))  # [b'5']

8.9 制作生成器
redis中没有提供列表的增量迭代, 如果想要循环name对应的列表所有元素, 需要自己定义.
如果列表非常发, 可能会撑爆内存, 每次值取值一部分值, 使用yield放回, 制作一个生成器.
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL)

# 写入数据
conn.lpush('l1', *[1, 2, 3, 4, 5, 6, 7, 8, 9, 10])


# 自定义生成器
def scan_list(name, count):
    # 定义初始值游标
    index = 0
    while True:
        data_list = conn.lrange(name, start=index, end=count + index - 1)
        # 取不值才结束
        if not data_list:
            return

        # 制作生成器
        for item in data_list:
            yield item

        # 移动游标, 每次移动count位
        index += count


for i in scan_list('l1', 2):
    print(i)

"""
b'10'
b'9'


b'2'
b'1'
"""

9. 管道

redis中使用管道实现事务. 要么都成功要么都失败, redis是非关系型数据库, 对事务的支持都不是很好(没有回滚).
账单操作都是使用关系型数据库
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL, decode_responses=True)

conn.set('user1', 100)
conn.set('user2', 100)


# transaction=True 开始事务
pipe = conn.pipeline(transaction=True)
pipe.multi()  # 在multi后面多条操作命令

user1_money = int(conn.get('user1')) - 20
pipe.set('user1', user1_money)

user2_money = int(conn.get('user2')) + 20
pipe.set('user2', user2_money)

pipe.execute()  # 支持上面的操作命令

print(conn.get('user1'))  # b'80'
print(conn.get('user2'))  # b'120'

10. 其他操作

10.1 查看所有键
keys: 查看redis中所有的键
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL, decode_responses=True)

print(conn.keys())  # [b'list16', b'user2', b'l1', b'user1']
"""
可以使用通配符 * - []  
"""
print(conn.keys('user*'))  # [b'user2', b'user1']
10.2 删除键
delete(key)  删除键
from connection_pool import POOL

import redis

conn = redis.Redis(connection_pool=POOL, decode_responses=True)

print(conn.keys())  # [b'list16', b'user2', b'l1', b'user1']

print(conn.delete('user1'))  # 1

print(conn.keys())  # [b'list16', b'user2', b'l1']

10.3 类方法生成对象
类调用方法生成连接对象
Redis.from_url('redis://127.0.0.1:6379/')
import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/')
print(conn.get('user2'))  # b'120'
10.4 执行redis命令
redis模块并没有把所有的redis命名都封装成方法, 如果没有该该方法使用execute方法去调用.
conn.execute_command(*args命令, **options参数)
import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/')
print(conn.execute_command('get', 'user2'))  # b'120'
10.5 判断键是否存在
exists(name) 判断键是否存在, 存在返回1, 不会在返回0.
import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/')
print(conn.exists('user2'))  # 1  
print(conn.exists('user1'))  # 0
10.6 设置超时
expire(key, timeout)  为key设置超时时间
import time
import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/')
print(conn.expire('user2', 1))  # Ture 设置超时时间
print(conn.get('user2'))  # b'120'

time.sleep(2)
print(conn.get('user2'))  # None

10.7 重命名
rename(src, dst) 
src 旧名字
dst 新名字
import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/', decode_responses=True)
conn.set('l1', '我叫l1')
print(conn.get('l1'))  # 我叫l1
print(conn.get('l2'))  # None

conn.rename('l1', 'l2')

print(conn.get('l1'))  # None
print(conn.get('l2'))  # 我叫l1

10.8 切换db库
move(name, db库名)
db库是自定生成的, 一般的不会去操作, 值是int.

image-20220525225308814

import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/', decode_responses=True)

conn.move('l2', 1)

image-20220525225400380

10.9 随机获取键
randomkey() 随机获取一个键
import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/', decode_responses=True)

conn.set('k1', 'v1')
conn.set('k2', 'v2')
conn.set('k3', 'v3')

print(conn.randomkey())  # k2
10.10 获取键的对应值的类型
import redis

conn = redis.Redis.from_url('redis://127.0.0.1:6379/', decode_responses=True)

conn.set('k1', 'v1')
conn.set('k2', 'v2')
conn.set('k3', 'v3')

print(conn.type('k2'))  # string

11. Django中使用redis

* 1. 通用方式: 使用redis模块, 生成连接对象去操作.
* 2. django_redis模块.(继承django的cache, 使用方式进而cache的使用一致, 
	数据被加密存到redis中, 不需要考虑数据类型.)
     1. pip install django_redis
     2. 在settings.py 配置文件中配置django_redis的信息
# CACHES 是Django的缓存配置
CACHES = {
        # 默认配置, 可以配置多个
        "default": {
            # Django缓存使用django_redis
            "BACKEND": "django_redis.cache.RedisCache",
            # redis的地址
            "LOCATION": "redis://127.0.0.1:6379",
            # 选项
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                # 连接池
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                # 密码
                # "PASSWORD": "123",
            }
        }
    }

image-20220526110651699

文件夹是自动创建的...
* 3. 使用 django_redis 生成连接对象(需要考虑数据类型)
from django_from django_redis import get_redis_connection

# 使用cache配置的default配置
conn = get_redis_connection('default')
conn.set('name', 'kid')

print(conn.get('name'))  # b'kid'
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值