Python 数据库骚操作 -- Redis

目录

  • 前言
  • Redis GUI 工具
  • Redis 遇上 Docker
  • Redis string
  • Redis hash
  • Redis list
  • Redis set
  • Redis zset
  • 后记

前言

前面一篇文章介绍了 MongoDB 的库,我把 MySQL 放在了最后面,这篇文章继续介绍 Redis 的操作。Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。接下来会简单介绍一下,Python 与 Redis 的化学反应。

Redis GUI 工具

首先介绍一款 Redis 的 GUI 工具 Medis,初学 Redis 用这个来查看数据真的很爽。可以即时看到数据的增删改查,不用操作命令行来查看。

主界面

操作界面图

Redis 遇上 Docker

关注我的人都知道,我的简介上面写着我的公众号会涉及 Docker 相关的知识,但最近的文章也没怎么涉及,所以后面的文章中,能跟 Docker 扯上关系的,我都会粗略地说一下。这里主要贴一贴配置代码,docker-compose 代码如下。

version: '3'
services:
  redis_container:
    image: redis
    command: redis-server --requirepass yourpassword # 配置 Redis 密码
    ports:
      - "6378:6379" # 映射端口
    volumes:
      - /your/path/data:/data 
复制代码

启动命令

docker-compose up -d
复制代码

Redis string

install

pip install redis
复制代码

连接

# 普通连接
r = redis.StrictRedis(host='localhost', port=6379, db=0)
r = redis.StrictRedis(host='localhost', port=6379, password="your password", db=0)

# 连接池
"""
redis-py 使用 connection pool 来管理对一个 redis server 的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池,这样就可以实现多个 Redis 实例共享一个连接池
"""
# host 是 redis 服务 ip,默认端口是6379
pool = redis.ConnectionPool(host='localhost', port=6379,decode_responses=True)  
r = redis.Redis(connection_pool=pool)
复制代码

增加

set(name, value, ex=None, px=None, nx=False, xx=False)

在Redis中设置值,默认,不存在则创建,存在则修改
参数:
ex,过期时间(秒)
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行
xx,如果设置为True,则只有name存在时,当前set操作才执行
复制代码
# 设置过期时间为 1 秒
r.set('foo', 'zone', ex=1)
# 效果同上
r.setex('foo', 'zone', 1)
# 效果同上
r.psetex('foo', 1000, 'zone')

print(r.get('foo'))

# 休眠两秒后,再打印输出
time.sleep(2)
print(r.get('foo'))
复制代码

查找

get(key)
普通查找
复制代码
print(r.get('foo'))
复制代码
mget(keys, *args)
批量查找
复制代码
# 批量获取
print(r.mget("k1", "k2"))  # 一次取出多个键对应的值
print(r.mget("k1"))
复制代码

获取子序列

getrange(key, start, end)
获取子序列(根据字节获取,非字符)
参数:
name,Redis 的 name
start,起始位置(字节)
end,结束位置(字节)
复制代码
# 一个汉字3个字节 1个字母一个字节
r.set("name", "zonezone")
print(r.getrange('name', 0, 3))
# 获取所有字节
print(r.getrange('name', 0, -1))

复制代码

获取结果

修改

原始值 zonezone ,修改后变为 zone is a boy

扫描二维码关注公众号,回复: 4052837 查看本文章
setrange(name, offset, value)
修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
参数:
offset,字符串的索引,字节(一个汉字三个字节)
value,要设置的值
复制代码
r.set("name", "zonezone")
r.setrange("name", 4, " is a boy")
print(r.get("name")) 
复制代码

修字符串成功

返回相应 key 的字符串长度

r.set("name", "zonezone")
print(r.strlen("name"))
复制代码

自增 name 对应的值(int)

incr(self, name, amount=1)
自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
参数:
name,Redis的name
amount,自增数(必须是整数)
复制代码
r.set("age", 123)
print(r.get("age"))
r.incr("age", amount=1)
print(r.get("age"))
复制代码

自增成功

自增 name 对应的值(float)

incrbyfloat(self, name, amount=1.0)
自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
参数:
name,Redis的name
amount,自增数(浮点型)
复制代码
r.set("age", 123.0)
print(r.get("age"))
r.incrbyfloat("age", amount=0.2)
print(r.get("age"))

复制代码

自减 name 对应的值

r.set("age", 123)
r.decr("age", amount=1) # 递减1
print(r.mget("foo1", "foo4"))
复制代码

追加内容

append(key, value)
在redis name对应的值后面追加内容
参数:
key, redis的name
value, 要追加的字符串
复制代码
r.set("name", "关注 ")
print(r.get("name"))
r.append("name","公众号【zone7】")
print(r.get("name"))
复制代码

Redis hash

hash

hset(name, key, value)
name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
参数:
name,redis的name
key,name对应的hash中的key
value,name对应的hash中的value
注:
hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)
复制代码
r.hset("hash1", "k1", "v1")
r.hset("hash1", "k2", "v2")
# 取hash中所有的key
print(r.hkeys("hash1")) 
# 单个取hash的key对应的值
print(r.hget("hash1", "k1"))    
# 多个取hash的key对应的值
print(r.hmget("hash1", "k1", "k2")) 
r.hsetnx("hash1", "k2", "v3")
print(r.hget("hash1", "k2"))
复制代码

批量增加与批量获取

# 批量增加
r.hmset("hash2", {"k1": "v1", "k2": "v2"})
# 批量获取
print(r.hmget("hash2", "k1", "k2"))
复制代码

去除所有 hash 键值对

print(r.hgetall("hash1"))
复制代码

获取 hash长度

hlen(name)
获取name对应的hash中键值对的个数
复制代码
print(r.hlen("hash1"))
复制代码

获取所有的keys(类似字典的取所有keys)

hkeys(name)
获取name对应的hash中所有的key的值
复制代码
print(r.hkeys("hash1"))
复制代码

获取所有的value(类似字典的取所有value)

hvals(name)
获取name对应的hash中所有的value的值
复制代码
print(r.hvals("hash1"))
复制代码

判断成员是否存在(类似字典的in)

hexists(name, key)
检查name对应的hash是否存在当前传入的key
复制代码
print(r.hexists("hash1", "k1")) 
复制代码

删除键值对

hdel(name,*keys)
将name对应的hash中指定key的键值对删除
复制代码
r.hset("hash1", "name", "zone")
print(r.hget("hash1", "name"))
r.hdel("hash1", "name")
print(r.hget("hash1", "name"))
复制代码

自增自减(int)

hincrby(name, key, amount=1)
自增name对应的hash中的指定key的值,不存在则创建key=amount
参数:
name,redis中的name
key, hash对应的key
amount,自增数(整数)
复制代码
r.hset("hash1", "age", 123)
r.hincrby("hash1", "age", amount=-1)
print(r.hget("hash1", "age"))
r.hincrby("hash1", "age", amount=1)  # 不存在的话,value默认就是1
print(r.hget("hash1", "age"))
复制代码

自增自减(float)

hincrbyfloat(name, key, amount=1.0)
自增name对应的hash中的指定key的值,不存在则创建key=amount
参数:
name,redis中的name
key, hash对应的key
amount,自增数(浮点数)
自增name对应的hash中的指定key的值,不存在则创建key=amount
复制代码
r.hset("hash1", "age", 123.0)
r.hincrbyfloat("hash1", "age", amount=-0.3)
print(r.hget("hash1", "age"))
r.hincrbyfloat("hash1", "age", amount=0.5)  # 不存在的话,value默认就是1
print(r.hget("hash1", "age"))
复制代码

Redis list

增加(不存在会自动创建)

lpush(name,values)
在name对应的list中添加元素,每个新的元素都添加到列表的最左边
rpush(name,values)
在name对应的list中添加元素,每个新的元素都添加到列表的最右边
复制代码
r.lpush("left_list", 11, 22, 33)
print(r.lrange('left_list', 0, -1))

r.rpush("right_list", 11, 22, 33)
print(r.lrange("right_list", 0, 3))

print(r.llen("right_list"))  # 列表长度
复制代码

添加(不存在不会自动创建)

lpushx(name,value)
在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边。不存在时,不会自动创建。
复制代码
r.lpushx("left_list", 2222)
print(r.lrange('left_list', 0, -1))

r.rpushx("right_list", 1111)
print(r.lrange('right_list', 0, -1))
复制代码

有两个 2222 是因为我手抖,多运行了一遍

新增

新增(固定索引号位置插入元素)
linsert(name, where, refvalue, value))
在name对应的列表的某一个值前或后插入一个新值
参数:
name,redis的name
where,BEFORE或AFTER
refvalue,标杆值,即:在它前后插入数据
value,要插入的数据
复制代码
# 往列表中左边第一个出现的元素"11"前插入元素"00"
r.linsert("left_list", "before", "11", "00") 
print(r.lrange("left_list", 0, -1))
复制代码

修改

修改(指定索引号进行修改)
r.lset(name, index, value)
对name对应的list中的某一个索引位置重新赋值
参数:
name,redis的name
index,list的索引位置
value,要设置的值
复制代码
r.lset("left_list", 0, "关注公众号【zone7】")    # 把索引号是0的元素修改成 关注公众号【zone7】
print(r.lrange("left_list", 0, -1))
复制代码

删除

删除(指定值进行删除)
r.lrem(name, value, num)
在name对应的list中删除指定的值
参数:
name,redis的name
value,要删除的值
num, num=0,删除列表中所有的指定值;
num=2,从前到后,删除2个; num=1,从前到后,删除左边第1个
num=-2,从后向前,删除2个
复制代码
# 将列表中左边第一次出现的"33"删除
r.lrem("left_list", "33", 1)   
print(r.lrange("left_list", 0, -1))
复制代码

删除 33

删除并返回

lpop(name)
在 name 对应的列表的左边获取第一个元素并在列表中移除,返回值则是第一个元素
rpop(name)
在 name 对应的列表的右边获取第一个元素并在列表中移除,返回值则是第一个元素
复制代码
print(r.lpop("left_list"))
print(r.lrange("list2", 0, -1))
复制代码

Redis set

增加

sadd(name,values)
添加元素
复制代码
r.sadd("set1", 1, 2, 3, 4)
# 获取集合长度
print(r.scard("set1"))  
# 获取集合中所有元素
print(r.smembers("set1")) 
复制代码

删除

# 普通删除
srem(name, values)
在name对应的集合中删除某些值
复制代码
 # 从集合中删除指定值 1
print(r.srem("set1", 1))  
print(r.smembers("set1"))
复制代码

删除了值 1

# 随机删除并返回被删除值
spop(name)
从集合移除一个成员,并将其返回,说明一下,集合是无序的,所有是随机删除的
复制代码
print(r.spop("set2"))   # 这个删除的值是随机删除的,集合是无序的
print(r.smembers("set2"))
复制代码

查找

# 普通获取
smembers(name)
获取name对应的集合的所有成员
复制代码
print(r.smembers("set1"))   # 获取集合中所有的成员
复制代码
# 以元组形式获取集合
sscan(name, cursor=0, match=None, count=None)
复制代码
print(r.sscan("set1"))
复制代码
# 以迭代器的方式获取集合
sscan_iter(name, match=None, count=None)
同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
复制代码
for i in r.sscan_iter("set1"):
    print(i)
复制代码

交集

sinter(keys, *args)
获取多个 name 对应集合的交集
复制代码
r.sadd("set2", 1, 2, 3, 4)
r.sadd("set3", 3, 4, 5, 6)
print(r.sinter("set2", "set3"))
复制代码

交集为 3、4

sinterstore(dest, keys, *args)
获取多个 name 对应集合的并集,再将并集加入到 dest(目标集合) 中
复制代码
r.sadd("set2", 1, 2, 3, 4)
r.sadd("set3", 3, 4, 5, 6)
print(r.sinterstore("set4", "set2", "set3"))
print(r.smembers("set4"))
复制代码

交集为 3、4

移动

smove(src, dst, value)
将某个成员从一个集合中移动到另外一个集合
复制代码
r.smove("set2", "set3", 3)
print(r.smembers("set2"))
print(r.smembers("set3"))
复制代码

将 set2 中的元素 3 移动至 set3

判断集合中是否有某元素

sismember(name, value)
检查value是否是name对应的集合的成员,结果为True和False
复制代码
print(r.sismember("set2", 3))
print(r.sismember("set3", 1))
复制代码

并集

sunion(keys, *args)
获取多个name对应的集合的并集
复制代码
r.sadd("set2", 1, 2, 3, 4)
r.sadd("set3", 3, 4, 5, 6)
print(r.sunion("set2", "set3"))
复制代码

无序集

并集--并集存在一个新的集合
sunionstore(dest,keys, *args)
获取多个name对应的集合的并集,并将结果保存到dest对应的集合中
复制代码
r.sadd("set2", 1, 2, 3, 4)
r.sadd("set3", 3, 4, 5, 6)
print(r.sunionstore("set4", "set2", "set3")) # 取2个集合的并集
print(r.smembers("set4"))
复制代码

无序集

Redis zset

set 就是无序,不允许重复的列表

增加

zadd(name, *args, **kwargs)
在name对应的有序集合中添加元素
复制代码
r.zadd("zset1", n1=123, n2=234)
print(r.zrange("zset1", 0, -1))   # 获取有序集合中所有元素
# 效果同上
r.zadd("zset1", 'n1', 123, 'n2', 234)
复制代码

删除

zrem(name, values)
删除name对应的有序集合中值是values的成员
复制代码
# 删除 n2
r.zrem("zset2", "n2")
print(r.zrange("zset2", 0, -1))
复制代码

n2 已被删除

zremrangebyrank(name, min, max)
根据索引删除
复制代码
# 根据索引删除
r.zremrangebyrank("zset2", 0, 1)
print(r.zrange("zset2", 0, -1))
复制代码

删除索引为 0、1 的值,即删除 n3、n4

zscore(name, value)
获取name对应有序集合中 value 对应的分数
复制代码
# 查找 n5 的值
print(r.zscore("zset2", "n5"))
复制代码

获取 set 的长度

print(r.zcard("zset1")) 
复制代码

获取有序集合的所有元素

r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
按照索引范围获取name对应的有序集合的元素
参数:
name,redis的name
start,有序集合索引起始位置(非分数)
end,有序集合索引结束位置(非分数)
desc,排序规则,默认按照分数从小到大排序
withscores,是否获取元素的分数,默认只获取元素的值
score_cast_func,对分数进行数据转换的函数
复制代码

从大到小排序(同zrange,集合是从大到小排序的)

zrevrange(name, start, end, withscores=False, score_cast_func=float)

# 只获取元素,不显示分数
print(r.zrevrange("zset1", 0, -1))    
# 获取有序集合中所有元素和分数,分数倒序
print(r.zrevrange("zset1", 0, -1, withscores=True))
复制代码

统计范围内元素个数

zcount(name, min, max)
获取name对应的有序集合中分数 在 [min,max] 之间的个数
复制代码
for i in range(1, 30):
    key = 'n' + str(i)
    r.zadd("zset2", key, i)
print(r.zrange("zset2", 0, -1, withscores=True))
print(r.zcount("zset2", 1, 9))
复制代码

太长了,我截取了部分

自增

zincrby(name, value, amount)
自增name对应的有序集合的 name 对应的分数
复制代码
# 每次将n1的分数自增5
r.zincrby("zset2", "n2", amount=5)
print(r.zrange("zset2", 0, -1, withscores=True))
复制代码

n1 已增加 5

获取值的索引号

zrank(name, value)
获取某个值在 name对应的有序集合中的索引(从 0 开始)
复制代码
# 获取 n2 的索引号
print(r.zrank("zset2", "n2"))
复制代码

后记

在微信公众号后台回复「Redis」获取源码。Redis 的骚操作就介绍到这里,后面会继续写 MySQL 的骚操作。尽请期待。

本文首发于公众号「zone7」,关注获取最新推文!

image

猜你喜欢

转载自juejin.im/post/5be996f5f265da615a415a09