#redis:5大数据类型---》字符串,链表,hash,集合,有序集合#redis支持5大数据类型,只支持到一层,第二层必须是字符串#Memcached:只支持字符串,都是纯内存
# redis:5大数据类型---》字符串,链表,hash,集合,有序集合
# redis支持5大数据类型,只支持到一层,第二层必须是字符串
# Memcached:只支持字符串,都是纯内存,断电数据丢失 redis可以持久化
redis字符串操作
重点:
'''
get
set
mget
mset
strlen
incrby
'''
from redis import Redis
cOnn= Redis(host='localhost', port=6379) # 默认链接本地
# 第三步操作数据
set
set(name, value, ex=None, px=None, nx=False, xx=False)
conn.set('name', 'zkj') # 设置键值对
conn.set('name', 'tom', ex=5) # ex 过期时间秒
conn.set('name', 'tom', px=3000) # px 过期时间毫秒
# nx,如果设置为True,则只有name不存在时,当前set操作才执行,若存在,不进行任何操作
conn.set('name', 'tom1', nx=True)
# xx 如果设置为True,则只有name存在是,当前set操作才执行,若不存在,不进行任何操作
conn.set('name', 'jason', xx=True)
setnx
setnx(name, value)
相当于 set(nx=True)
conn.setnx('age', '18')
psetex
psetex(name, time_ms, value)
# 以毫秒计时,到期键值对消失
conn.psetex('name', 3000, 'kevin')
mset
mset(*args, **kwargs)
批量设置
conn.mset({'name': 'zkj', 'age': 16, 'hobby': 'women'})
get(name)
获取值
print(conn.get('name'))
mget
mget(keys, *args)
批量获取
print(conn.mget('name', 'age', 'hobby')) # 以列表形式返回值
getset
getset(name, value)
# 获取并设置值,获取的原来的值,设置一个新值,如果原来没有该键,会获取到一个None,然后设置一个新的值
print(conn.getset('name', 'llnb'))
getrange
getrange(key, start, end)
# 根据起始和终止位置,获取字符串,以字节计数,由此得知,redis中的存储使用utf-8存储的
print(conn.getrange('name', 0, 2).decode('utf8'))
setrange
setrange(name, offset, value)
# 根据起始位置,以字节计数,来设置字符串,按照字节来修改(一个中文占三个字节 )
conn.setrange('name', 3, 1231)
setbit
setbit(name, offset, value)
# 修改指定位置的比特位,字符与字符编码表对应,改变比特,相当于改变字符
conn.setbit('name', 7, 0)
setbit
setbit(name, offset, value)
# 修改指定位置的比特位,字符与字符编码表对应,改变比特,相当于改变字符
conn.setbit('name', 7, 0)
getbit
getbit(name, offset)
# 获取对应位置的比特位是否是0
print(conn.getbit('name', 3))
bitcount
bitcount(key, start=None, end=None)
# 获取起始位置到终止位置的字符中的比特位有多少个1
print(conn.bitcount('name', 0, 4))
strlen
strlen(name)
# 12 strlen(name)
# 统计key对应的值的字节长度
print(conn.strlen('name'))
incr
incr(self, name, amount=1)
# 计数器
conn.incrby('age')
incrbyfloat
incrbyfloat(self, name, amount=1.0)
# 计数器,支持浮点--->amount
conn.incrbyfloat('age', amount=1.1)
decr
decr(self, name, amount=1)
# 计数器---> 减
conn.decrby('age')
append
append(key, value)
# 在key对应的value最后添加字符
conn.append('name', 'sb')
conn.close() # 关闭服务
redis操作hash
重点:
'''
hset
hget
hlen
hexists
hincrby
'''
hset
hset(name, key, value)
mapping--> 一次性设置多个键值对
# 1 hset(name, key, value)
# 相当于--> 名字--->{'name':'zkj'}
conn.hset('userinfo', 'name', 'zkj')
# mapping--> 一次性设置多个键值对
conn.hset('userinfo', mapping={'name': 'zkj', 'age': 18})
hmset
设置多个键值对(已经被弃用)
hmset(name, mapping)
conn.hmset('userinfo1', {'name': 'zkj', 'age': 10}) # 可能会报错
'''
error:DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead.
conn.hmset('userinfo1', {'name': 'zkj', 'age': 10})
'''
hget
获取某个名字里的某个key对应的value
hget(name,key)
# 获取某个名字里的某个key对应的value
print(conn.hget('userinfo', 'name'))
hmget
批量获取
hmget(name, keys, *args)
print(conn.hmget('userinfo', ['name', 'age']))
hgetall
获取该名字下所有
慎用---》如果hash类型数据量特别大,很可能撑爆内存
hgetall(name)
print(conn.hgetall('userinfo'))
hlen
获取该名字下有多少个键值对
hlen(name)
print(conn.hlen('userinfo'))
hkeys
获取该名字下所有的key
hkeys(name)
print(conn.hkeys('userinfo'))
hvals
hvals(name)
获取该名字下所有的value
print(conn.hvals('userinfo'))
hexists
hexists(name, key)
获取该名字下有没有对应的key,返回True\False
print(conn.hexists('userinfo', 'name'))
hdel
删除该名字下的对应的key
hdel(name,*keys)
conn.hdel('userinfo', 'name')
hincrby
计数器--->增加
hincrby(name, key, amount=1)
conn.hincrby('userinfo','age')
hincrbyfloat
hincrbyfloat(name, key, amount=1.0)
支持小数的计数器
conn.hincrbyfloat('userinfo', 'age', amount=1.1)
hscan
hscan(name, cursor=0, match=None, count=None)
# 注意一下---》不建议使用hgetall---》分批取值
# 先制造一些数据
for i in range(1000):
conn.hset('htest', 'name_%s' % i, '鸡_%s' % i)
res = conn.hgetall('htest')
print(res)
# >这个不是直接用,需要配合hscan_iter来用
res = conn.hscan('htest', cursor=0, count=35)
print(res)
print(len(res[1]))
hscan_iter
hscan_iter(name, match=None, count=None)
把htest数据全取出来打印,批量获取,每次取10条
for item in conn.hscan_iter('htest', count=10):
print(item)
redis操作链表(list)
lpush
lpush(name,values)
在列表的‘左边’添加元素,每次第一个新增的会在最下面
conn.lpush('name2', 'tom')
conn.lpush('name2', 'jerry')
lpushx
lpushx(name,value)
只有name已经存在时才会进行操作
conn.lpushx('name2', 'jason')
rpushx
rpushx(name, value)
表示从右向左操作
conn.rpushx('name2', 'zkj')
llen
llen(name)
查看某个列表内有多少个元素
print(conn.llen('name2'))
linsert
linsert(name, where, refvalue, value))
在name对应的列表的某一个值前或后插入一个新值
# 参数:
# name,redis的name
# where,BEFORE或AFTER(小写也可以)
# refvalue,标杆值,即:在它前后插入数据(如果存在多个标杆值,以找到的第一个为准)
# value,要插入的数据
conn.linsert('name2', 'before', 'zkj', 'st')
lset
lset(name, index, value)
对name对应的list中的某一个索引位置重新赋值
# 参数:
# name,redis的name
# index,list的索引位置
# value,要设置的值
conn.lset('name2', 3, 'wh')
lrem
lrem(name, value, num)
正数是从左侧,负数是从右侧,0表示删所有
在name对应的list中删除指定的值
# 参数:
# name,redis的name
# value,要删除的值
# num, num=0,删除列表中所有的指定值;
# num=2,从前到后,删除2个;
# num=-2,从后向前,删除2个
conn.lrem('name2', 1, 'jason')
conn.lrem('name2', -1, 'tom')
lpop
从左侧弹出
lpop(name)
print(conn.lpop('name2'))
lindex
lindex(name, index)
根据索引查找某个值,在name对应的列表中根据索引获取列表元素
res = conn.lindex('name2', 2)
print(res.decode('utf8'))
lrange
lrange(name, start, end)
# 在name对应的列表分片获取数据
# 参数:
# name,redis的name
# start,索引的起始位置
# end,索引结束位置
print(conn.lrange('name2', 0, 2))
print(re.lrange('aa',0,re.llen('aa')))
ltrim
ltrim(name, start, end)
在name对应的列表中移除没有在start-end索引之间的值
# 参数:
# name,redis的name
# start,索引的起始位置
# end,索引结束位置(大于列表长度,则代表不移除任何)
# conn.ltrim('name2', 0, 2)
rpoplpush
从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
# 参数:
# src,要取数据的列表的name
# dst,要添加数据的列表的name
conn.lpush('name3', 'aa')
conn.rpoplpush('name2', 'name4')
blpop
blpop(keys, timeout)
将多个列表排列,按照从左到右去pop对应列表的元素
# 参数:
# keys,redis的name的集合
# timeout,超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
# 更多:
# r.brpop(keys, timeout),从右向左获取数据爬虫实现简单分布式:多个url放到列表里,往里不停放URL,程序循环取值,但是只能一台机器运行取值,可以把url放到redis中,多台机器从redis中取值,爬取数据,实现
print(conn.blpop('zkj'))
brpoplpush
从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
brpoplpush(src, dst, timeout=0)
# 参数:
# src,取出并要移除元素的列表对应的name
# dst,要插入元素的列表对应的name
# timeout,当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞
conn.brpoplpush('name3', dst='tom', )
自定义增量迭代
# 由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要:
# 1、获取name对应的所有列表
# 2、循环列表
# 但是,如果列表非常大,那么就有可能在第一步时就将程序的内容撑爆,所有有必要自定义一个增量迭代的功能:
import redis
cOnn=redis.Redis(host='127.0.0.1',port=6379)
# conn.lpush('test',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
# conn.flushall()
def scan_list(name,count=2):
index=0
while True:
data_list=conn.lrange(name,index,count+index-1)
if not data_list:
return
index+=count
for item in data_list:
yield item
print(conn.lrange('test',0,100))
for item in scan_list('test',5):
print('---')
print(item)
## 面试题————》哪里用过生成器迭代器
# 公司里有个很大的redis的列表,我想吧列表的值取出来,取出来我不是直接取出所有,而是用的自定义增量迭代,使用生成器来做的,每次取几条。每次取几条