1 redis普通连接和连接池
1.1 普通连接
1.2 连接池
2 redis字符串类型
3 redis hash类型
4 redis列表类型
#1 python 代码作为客户端---》连接
# 2 安装模块:pip install redis
from redis import Redis
conn = Redis(host="localhost",port=6379,db=0,decode_responses=True)
res=conn.get('name')
print(res)
conn.close()
import redis
# 把池写成单例----》整个项目中,只有这一个实例(对象)---》python 中实现单例的5种方式---》模块导入的方式
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=50)
######
import redis
from threading import Thread
from pool import POOL
def task():
conn = redis.Redis(connection_pool=POOL)
print(conn.get('name'))
conn.close()
if __name__ == '__main__':
for i in range(10):
t = Thread(target=task)
t.start()
'''
1 set(name, value, ex=None, px=None, nx=False, xx=False)
2 setnx(name, value)
3 setex(name, value, time)
4 psetex(name, time_ms, value)
5 mset(*args, **kwargs)
6 get(name)
7 mget(keys, *args)
8 getset(name, value)
9 getrange(key, start, end)
10 setrange(name, offset, value)
11 setbit(name, offset, value)
12 getbit(name, offset)
13 bitcount(key, start=None, end=None)
14 bitop(operation, dest, *keys)
15 strlen(name)
16 incr(self, name, amount=1)
# incrby
17 incrbyfloat(self, name, amount=1.0)
18 decr(self, name, amount=1)
19 append(key, value)
'''
代码演练19个字符串类型:
import redis
conn = redis.Redis(decode_responses=True)
# 1 set(name, value, ex=None, px=None, nx=False, xx=False)
# conn.set('age','19') # 没有就新增,有值就修改
# conn.set('hobby','篮球',ex=5) # ex过期时间 秒
# conn.set('hobby','篮球',px=5000)# 过期时间,毫秒
# conn.set('name','彭于晏')
# conn.set('name', 'lqz', nx=True) # nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
# conn.set('name', 'lqz', xx=True) # 如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
# 2 setnx(name, value)
# conn.setnx('name','彭于晏')
# 3 setex(name, value, time)
# conn.setex('name',5,'sdasdfs')
# 4 psetex(name, time_ms, value)
# conn.psetex('name',5000,'lqz')
# 5 mset(*args, **kwargs) 批量设置
# conn.mset({'name': 'lqz', 'age': 29, 'gender': '男'})
# 6 get(name)
# print(conn.get('name'))
# 7 mget(keys, *args)
# print(conn.mget(['name','age']))
# print(conn.mget('name','age','gender'))
# 8 getset(name, value) # 等同于 get set
# print(conn.getset('name','oooo'))
# 9 getrange(key, start, end)
# print(conn.getrange('name',1,3)) # 前闭后闭区间
# 10 setrange(name, offset, value)
# conn.setrange('name',2,'ooo') # 包含2
# 先不聊---》操作比特位---》后面聊
# 11 setbit(name, offset, value)
# conn.setbit('name',7,1) # l=[1 1 0 0 0 1 0 0 ]
# 12 getbit(name, offset)
# 13 bitcount(key, start=None, end=None)
# 14 bitop(operation, dest, *keys)
# 15 strlen(name)
# print(conn.strlen('name'))
# 16 incr(self, name, amount=1)
# conn.incr('age',2) # 自加1,单线程,没有并发安全,数据不会错乱,天然适合计数器 计数器---》日活(日活跃用户数,只要有用户登录,就+1)
# # incrby
# 17 incrbyfloat(self, name, amount=1.0)
# conn.incrbyfloat('age',1.1)
# 18 decr(self, name, amount=1)
# conn.decr('age')
# 19 append(key, value)
# conn.append('name','ooo')
conn.close()
'''
set
get
getrange
strlen
'''
'''
1 hset(name, key, value)
2 hmset(name, mapping)
3 hget(name,key)
4 hmget(name, keys, *args)
5 hgetall(name)
6 hlen(name)
7 hkeys(name)
8 hvals(name)
9 hexists(name, key)
10 hdel(name,*keys)
11 hincrby(name, key, amount=1)
12 hincrbyfloat(name, key, amount=1.0)
13 hscan(name, cursor=0, match=None, count=None)
14 hscan_iter(name, match=None, count=None)
'''
def hscan_iter(self,name,match= None,count= None):
cursor = "0"
while cursor != 0:
cursor, data = self.hscan(name, cursor=cursor, match=match, count=count)
yield from data.items()
代码演练14个hash类型:
''' hash 类型,就是咱们python中的字典类型, 数据结构:数据的组织形式 底层存储 数组---》根据key值使用hash函数得到结构,存到数组中
字典的key值必须可hash
字典的key值必须是不可变数据类型
hash 类型无序,跟放的先后顺序无关的
python 的字典是 有序的 字典+列表
'''
# print(hash(1))
# print(hash('asdfasdf'))
# # print(hash([1,2,3,])) # unhashable
# print(hash((1,2,3))) # 不可变数据类型
# a={(1,2,3):8}
# print(a[(1,2,3)])
# class Person(object):
# pass
# p=Person()
#
# a={p:'asdf'}
# print(a[p])
import redis
conn = redis.Redis(decode_responses=True)
# 1 hset(name, key, value)
# conn.hset('userinfo','name','lqz')
# conn.hset('userinfo','age','19')
# 2 hmset(name, mapping) 弃用了,统一用hset
# conn.hmset('userinfo2',{'name':'pyy',"age":33})
# conn.hset('userinfo3',mapping={'name':'xxx',"age":33})
# 3 hget(name,key)
# print(conn.hget('userinfo','name'))
# 4 hmget(name, keys, *args)
# print(conn.hmget('userinfo',['name','age']))
# print(conn.hmget('userinfo','name','age'))
# 5 hgetall(name) # 慎用---》userinfo 对应的value值非常多,一次性拿出来,很耗时
# print(conn.hgetall('userinfo'))
# 6 hlen(name)
# print(conn.hlen('userinfo'))
# 7 hkeys(name)
# print(conn.hkeys('userinfo'))
# 8 hvals(name)
# print(conn.hvals('userinfo'))
# 9 hexists(name, key)
# print(conn.hexists('userinfo','hobby'))
# 10 hdel(name,*keys)
# conn.hdel('userinfo',['name','age'])
# conn.hdel('userinfo','name','age')
# 11 hincrby(name, key, amount=1)
# conn.hincrby('userinfo2','age')
# 12 hincrbyfloat(name, key, amount=1.0)
# 13 hscan(name, cursor=0, match=None, count=None) # 不单独用
## 造数据
# for i in range(1000):
# conn.hset('hash2','egg_%s'%i,'鸡蛋%s号'%i)
# count 数字是大致的 大小,如果拿了10 ,可能是9 可能是11
# res=conn.hscan('hash2',cursor=0,count=10) # 无序,所以不是从egg_0开始的
# print(len(res[1]))
# 14 hscan_iter(name, match=None, count=None) # 替代hgetall,一次性全取出值,如果占内存很大,会有风险 , 使用hscan_iter 分批获取值,内存占用很小
for item in conn.hscan_iter('hash2',count=10):
print(item)
# 分批获取数据
conn.close()
'''
hset
hget
hlen
hexists
hincrby
hscan_iter
'''
'''
1 lpush(name, values)
2 rpush(name, values) 表示从右向左操作
3 lpushx(name, value)
4 rpushx(name, value) 表示从右向左操作
5 llen(name)
6 linsert(name, where, refvalue, value))
7 r.lset(name, index, value)
8 r.lrem(name, value, num)
9 lpop(name)
10 rpop(name) 表示从右向左操作
11 lindex(name, index)
12 lrange(name, start, end)
13 ltrim(name, start, end)
14 rpoplpush(src, dst)
15 blpop(keys, timeout)
16 r.brpop(keys, timeout),从右向左获取数据
17 brpoplpush(src, dst, timeout=0)
'''
代码演练17个列表类型:
import redis
conn = redis.Redis(decode_responses=True)
# 1 lpush(name, values)
# conn.lpush('girls','刘亦菲','迪丽热巴')
# conn.lpush('girls','小红')
# 2 rpush(name, values) 表示从右向左操作
# conn.rpush('girls', '小绿')
# 3 lpushx(name, value) # 只有key存在,才能追加
# conn.lpushx('girls','小紫')
conn.lpushx('girls1', '小紫')
# 4 rpushx(name, value) 表示从右向左操作
# 5 llen(name)
# print(conn.llen('girls'))
# 6 linsert(name, where, refvalue, value))
# conn.linsert('girls', where='before', refvalue='刘亦菲', value='新刘亦菲')
# conn.linsert('girls', where='after', refvalue='刘亦菲', value='老刘亦菲')
# 7 r.lset(name, index, value)
# conn.lset('girls',0,'oooo') # 按索引修改某个位置值
# 8 r.lrem(name, value, num)
# conn.lrem('girls',1,'刘亦菲') # 从左侧删一个
# conn.lrem('girls',-1,'刘亦菲') # 从右侧删一个
# conn.lrem('girls',0,'刘亦菲') # 全删除
# 9 lpop(name)
# print(conn.lpop('girls')) # 左侧弹出一个
# print(conn.rpop('girls')) # 右侧弹出
# 10 rpop(name) 表示从右向左操作
# 11 lindex(name, index)
# print(conn.lindex('girls',0))
# 12 lrange(name, start, end)
# print(conn.lrange('girls',1,10000)) # 前闭后闭
# 一次性把列表中数据都取出来
# print(conn.lrange('girls', 0, -1)) # 可以用-1
# print(conn.lrange('girls', 0, conn.llen('girls'))) # 可以用-1
# 13 ltrim(name, start, end)
# conn.ltrim('girls',2,4)
# 14 rpoplpush(src, dst)
# conn.rpoplpush('girls','girls')
# 15 blpop(keys, timeout) # block:阻塞 实现分布式的系统 消息队列
res=conn.blpop('girls',timeout=5)
print(res)
# 16 r.brpop(keys, timeout),从右向左获取数据
# 17 brpoplpush(src, dst, timeout=0)
conn.close()
# utf-8 编码的 bytes格式
# b=b'\xe8\xbf\xaa\xe4\xb8\xbd\xe7\x83\xad\xe5\xb7\xb4'
# print(b.decode('utf-8'))
#
# for i in b:
# print(bin(i))
'''
lpush
rpush
llen
lrange
lpop
'''