day09——Redis
Redis介绍和安装
# Redis:软件,存储数据的,速度非常快,Redis是一个key-value存储系统(没有表的概念),cs架构的软件
服务端 客户端(python作为客户端,java,go都可以,图形化界面,命令窗口的命令)
# es:存数据的地方
# 关系型数据库和非关系型数据库
关系型:mysql,PostgreSQL,Oracle,SQLserver,db2
去 IOE:国产化
IBM---》浪潮信息,曙光,联想
Oracle---》数据----》达梦。。。。
EMC存储---》国产存储
非关系型数据库(nosql):redis(缓存),MongoDB(json文档数据存储),es(大数据量存储)
nosql 指非关系型数据库:not only sql,对关系型数据库的补充
# Redis特点:
开源软件,存数据,cs架构
key-value存储,5大数据类型 value的类型是5种:字符串,hash(字典),列表,集合,有序集合
速度快:
1.纯内存存储(核心)
2.使用了IO多路复用的网络模型
3.数据操作是单线程,避免了线程间切换,而且没有锁,也不会数据错乱
支持持久化
纯内存,可以存到硬盘上,防止数据丢失
redis又被称为 缓存数据库
安装Redis
# redis 是用c语言编写的,需要在不同平台编译成可执行文件,才能在这个平台上运行
redis 使用了io多路复用中的epoll模型,win不支持epoll
redis官方,不支持win版本
微软官方,就把redis改动,编译成可执行,能运行在win上,滞后 3.x版本
第三方:5.x版本
# redis 官方网:https://redis.io/download/
# redis中文网:http://redis.cn
# win:3.x:https://github.com/microsoftarchive/redis/releases
# win:5.x:https://github.com/tporadowski/redis/releases/
# 安装:一路下一步
安装完成后,在安装路径下有
redis-cli.exe # mysql
redis-server.exe # mysqld
redis.windows-service.conf # my.ini
并且会自动做成服务
服务的命令:redis-server.exe redis.windows-service.conf
# 启动redis服务端
1 命令行中 redis 就可以启动服务
2 命令行中,启动服务,并指定配置文件
redis-server 配置文件路径
3 使用服务启动
# 客户端链接
1 命令行客户端:
redis-cli # 默认连本地的6379端口
redis-cli -p 6379 -h 127.0.0.1
2 图形化客户端链接
1 最新版的Navicate支持链接redis了(收费的)
2 Redis Desktop Manager(https://resp.app/) 收费的 用的多 qt写图形化界面
qt是个平台,做GUI[图形化界面]开发
用c写,用python写 pyqt5
3 python的模块
pip install redis
Redis普通链接和连接池
1.普通链接
from redis import Redis
# 建立Redis链接
# conn = Redis()
conn = Redis(
host="127.0.0.1", # 链接地址
port=6379, # 链接端口 默认是6379
db=0, # 链接本地Redis的指定db 默认是0
decode_responses=True # 查询回来返回的结果是字符串类型,否则是byte格式,默认用utf-8编码
)
res = conn.get('name')
print(res) # 获取key名为name的value值
conn.close() # 关闭链接
2.连接池链接
# 一定要保证,池是单例的,以模块导入的形式做成了单例
# pool.py
import redis
POOL = redis.ConnectionPool(max_connections=1000,host='127.0.0.1',port=6379)
# 其它.py
import redis
from pool import POOL # 模块导入的方式, 天然单例
conn = redis.Redis(connection_pool=POOL) # 以后拿到链接,是从POOL种取,如果没有可用的了,默认不阻塞,可以通过某个参数配置,设置阻塞等待
res = conn.get('name') # 获取key名为name的value值
print(res)
conn.close() # 关闭链接
Redis字符串类型
import redis
conn = redis.Redis()
# 1 set(name, value, ex=None, px=None, nx=False, xx=False)
# 在Redis中设置值,默认,不存在则创建,存在则修改
"""
参数:
ex,过期时间(秒)
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
"""
# conn.set('age','18',ex=3)
# conn.set('age','18',px=3000)
# conn.set('age','20',nx=True)
# conn.set('age','20',xx=True)
# 2 setnx(name, value)
# conn.setnx('age', '20') # 等同于conn.set('age', '20', nx=True)
# 3 psetex(name, time_ms, value)
"""
参数:
time_ms,过期时间数字毫秒 或 timedelta对象
"""
# conn.psetex('hobby',3000,'足球')
# 4 mset(*args, **kwargs) 批量设置
# conn.mset({'name':'xxx', 'age':'18'})
# 5 get(name) 获取值
# print(conn.get('name'))
# 6 mget(keys, *args) 批量获取
# print(conn.mget('name', 'age')) # [b'xxx', b'18']
# 7 getset(name, value) 设置新值并获取原来的值
# print(conn.getset('name', 'zzz')) # b'yyy'
# 8 getrange(key, start, end)
"""
参数:
start:起始位置(字节)
end:结束位置(字节)
"""
# print(conn.getrange('name', 0, 1)) # b'zz' 前闭后闭
# 9 setrange(name, offset, value)
# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
"""
参数:
offset:字符串的索引
value:要设置的值
"""
# conn.setrange('name',1,'abc')
# 14 strlen(name)
# 返回name对应值的字节长度(一个汉字3个字节)
# print(conn.strlen('name'))
# 15 incr(self, name, amount=1)
# 自增 name对应的值,当name不存在时,则创建,否则,则自增。
# conn.incr('age',amount=1)
# conn.incr('height',amount=1)
# 16 incrbyfloat(self, name, amount=1.0)
# 同上 但amount可以是整型也可以是浮点型
# conn.incrbyfloat('height',amount=1.5)
# conn.incrbyfloat('height',amount=2)
# 17 decr(self, name, amount=1)
# 自减 name对应的值,当name不存在时,则创建,否则,则自减。
# conn.decr('age',amount=1)
# conn.decr('xx',amount=1)
# 18 append(key, value)
# conn.append('name','haha')
# 重点掌握
get set strlen append
RedisHash类型
import redis
conn = redis.Redis(decode_responses=True)
# 1 hset(name, key, value)
"""
参数:
name,redis的name
key,name对应的hash中的key
value,name对应的hash中的value
"""
# conn.hset('userinfo','name','xxx')
# 2 hmset(name, mapping) # 弃用了,还能用
"""
参数:
name:redis中的name
mapping:字典
"""
# conn.hmset('userinfo',{'age':'18','hobby':'足球'})
# 3 hget(name,key)
# print(conn.hget('userinfo', 'name'))
# 4 hmget(name, keys, *args) 获取多个 两种写法
# print(conn.hmget('userinfo', ['name', 'age', 'hobby']))
# print(conn.hmget('userinfo','name','age','hobby'))
# 5 hgetall(name) 获取所有的键值对 慎用,如果hash中key非常的,可能会撑爆内存
# print(conn.hgetall('userinfo'))
# 6 hlen(name) 获取键值对的个数
# print(conn.hlen('userinfo'))
# 7 hkeys(name) 获取对应的hash中所有的key的值
# print(conn.hkeys('userinfo'))
# 8 hvals(name) 获取name对应的hash中所有的value的值
# print(conn.hvals('userinfo'))
# 9 hexists(name, key) 判断userinfo是否存在这个键
# print(conn.hexists('userinfo','name'))
# 10 hdel(name,*keys) 删除指定key的键值对
# conn.hdel('userinfo','hobby','age')
# 11 hincrby(name, key, amount=1) 自增对应的hash中键值对的值
# conn.hincrby('userinfo','age',amount=1)
# 12 hincrbyfloat(name, key, amount=1.0) 自增
# conn.hincrbyfloat('userinfo','height',amount=1.5)
# 13 他们是一家
# for i in range(1000):
# conn.hset('hash_test','egg_%s' % i,'鸡蛋%s号' % i)
# hscan(name, cursor=0, match=None, count=None) 分批获取,获取多少个,约等于,它不单独用
"""
参数:
cursor:游标(基于游标分批获取数据)
match:匹配指定key,默认none,表示所有
count:每次分批最少获取的个数 10
"""
# res = conn.hscan('hash_test', cursor=0, match=None, count=None)
# print(res)
# print(len(res[1]))
# res = conn.hscan('hash_test',cursor=0,count=10)
# print(res)
# print(len(res[1]))
# hscan_iter(name, match=None, count=None) 获取所有,但是分批获取
for item in conn.hscan_iter('hash_test',count=10): # 取出所有,每次拿10条,用完再取10条,直到取完,内部使用了hscan+生成器
print(item)