redis列表 hash 其他操作 redis管道

回顾

1.登录注册前端
	登录
  手机验证码登录 --->>> 输入手机号 --->>> 监听失去焦点事件 --->>> 手机号正则校验(js),查询手机号是否存在 --->>> 发送验证码的按钮可以点击 --->>> 点击发送验证码按钮 --->>> ajax发送验证码 --->>> 起了个定时任务 --->>> 手机收到了验证码,填入验证码框 --->>> 点击登录按钮 --->>> 向后端发送登录ajax请求 --->>> 返回给前端token和username --->>> 前端保存到cookie中 --->>>> 子传父,关闭了登录模态框 --->>> 在header.vue取了一下token和username
  多方式登录 --->>> 输入用户名和密码后 --->>> 点击登录 --->>> 后端登录成功,返回username和token --->>> 后面的同上。。。
  
  注册
  输入手机号码 --->>> 监听失去焦点事件 --->>> 手机号正则校验(js),查询手机号是否存在,如果不存在 --->>> 发送验证码的按钮可以点击 --->>> 点击发送验证码按钮 --->>> ajax发送验证码 --->>> 起了个定时任务 --->>> 手机收到了验证码,填入验证码框 --->>> 填入密码 --->>> 点击注册 --->>> 调用注册接口完成注册 --->>>子传父 --->>> Register.vue --->>> 显示出Login.vue
  
 
# 2.redis 介绍
	数据库,非关系型数据库,缓存数据库,key-value形式存储,数据都在内存中,有5大数据类型,速度非常快,数据操作是单线程,不存在并发安全的问题
  redis的缓存更新策略
    为什么这么快:
    1.纯内存操作
    2.高性能的网络模型,IO多路复用(epoll)
    3.单线程,不存在线程间切换
  
  redis版本
  	7.x	最新
    6.x	从它后,多进程,多线程架构
    5.x及之前 单进程单线程架构
    
  
  进程:资源分配的最小单位,一个程序的运行,可能一个进程,也可能多个进程
  线程:cpu调度的最小单位,遇到IO操作,操作系统层面切换
  协程:单线程下的并发,程序层面控制,遇到IO操作,切换到别的任务执行
  
# 3.安装redis
	mac		编译完成了,bin路径下,redis-server	redis-cli
  linux		编译安装
  win			专门的安装包
  
  安装问成会有两个命令:启动服务端,启动客户端, cs架构的软件
  客户端和服务端在同一台机器上
  本地的客户端可以连接远程的服务端
  mysql 也是cs架构软件
  	pymysql:是mysql的客户端
    Navicat:是mysql客户端
    -功语言操作mysql:是mysql客户端
    
 	启动redis服务
  	redis-server 指定配置文件
    使用服务启动
  客户端连接
  	cmd中使用redis-cli
    图形化界面
    python的redis模块操作redis
    
 
# 4.python连接redis
	普通连接
  连接池连接:单例模式
    
  Django使用mysql连接池
  
# redis 5大数据类型(字符串、列表、hash、集合、有序集合)之字符串 是指value值是字符串
	get
  set
  strlen
  mset
  getrang

redis之列表

有序可重复

image-20230308161347286

'''
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)

'''

import redis

conn = redis.Redis()
# 1 lpush(name, values)   从左侧插入
  conn.lpush('girls', '刘亦菲', '迪丽热巴')
  conn.lpush('girls', '周淑怡')

# 2 rpush(name, values) 表示从右向左操作
	conn.rpush('girls', '小红')

# 3 lpushx(name, value)
   conn.lpushx('boys','小刚')
   conn.lpush('boys','小刚')
   conn.lpushx('girls','小刚')


# 4 rpushx(name, value) 表示从右向左操作


# 5 llen(name) 	统计value的数量
	 res = conn.llen('girls')
	 print(res)
# 6 linsert(name, where, refvalue, value))

	 conn.linsert('girls','before','迪丽热巴','古力娜扎') 基于指定位置插入
	 conn.linsert('girls', 'after', '小红', '小绿')

	 conn.linsert('girls', 'after', '小黑', '小嘿嘿')  # 没有标杆,插入不进去


# 7 r.lset(name, index, value)  # 按位置改值 从0开始
	 conn.lset('girls',1,'xxx')

# 8 r.lrem(name, value, num)

 	conn.lrem('girls',1,'xxx')  # 从左侧开始,删除1个
	conn.lrem('girls',-1,'xxx')  # 从右侧开始,删除1个
	conn.lrem('girls',0,'xxx')  # 从左开始,全删除

# 9 lpop(name)
	res=conn.lpop('girls')
	print(res)


# 10 rpop(name) 表示从右向左操作

# 11 lindex(name, index)
	res = str(conn.lindex('girls', 1), encoding='utf-8')
	print(res)

# 12 lrange(name, start, end)
	res=conn.lrange('girls',0,0)   # 前闭后闭区间
	print(res)


# 13 ltrim(name, start, end)
	conn.ltrim('girls',2,3)


# 14 rpoplpush(src, dst)

# 15 blpop(keys, timeout)  # 记住 ,可以做消息队列使用  阻塞式弹出,如果没有,就阻塞
	res=conn.blpop('boys')
	print(res)

# 16 r.brpop(keys, timeout),从右向左获取数据
# 17 brpoplpush(src, dst, timeout=0)

conn.close()


'''
lpush
lpop
llen
lrange
'''

redis之hash

image-20230308170820887

'''
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)

'''

import redis

conn = redis.Redis()
# 1 hset(name, key, value)
	 conn.hset('userinfo','name','lqz')
 	conn.hset('userinfo',mapping=	{'age':19,'hobby':'篮球'})

# 2 hmset(name, mapping)   # 批量设置,被弃用了,以后都使用hset
	 conn.hmset('userinfo2',{'age':19,'hobby':'篮球'})

# 3 hget(name,key)
	 res=conn.hget('userinfo','name')
	 print(res)

# 4 hmget(name, keys, *args)
	res=conn.hmget('userinfo',['name','age'])
	res = conn.hmget('userinfo', 'name', 'age')
	print(res)

# 5 hgetall(name)  # 慎用
	res=conn.hgetall('userinfo')
	print(res)

# 6 hlen(name)
	res=conn.hlen('userinfo')
	print(res)

# 7 hkeys(name)
	res=conn.hkeys('userinfo')
	print(res)

# 8 hvals(name)
	res=conn.hvals('userinfo')
	print(res)

# 9 hexists(name, key)
	res = conn.hexists('userinfo', 'name')
	res = conn.hexists('userinfo', 'name1')
	print(res)

# 10 hdel(name,*keys)
	res = conn.hdel('userinfo', 'age')
	print(res)

# 11 hincrby(name, key, amount=1)
	conn.hincrby('userinfo', 'age', 2)
	article_count ={
    '1001':0,
     '1002':2,
     '3009':9
 }

# 12 hincrbyfloat(name, key, amount=1.0)

hgetall  会一次性全取出,效率低,可以能占内存很多
 分批获取,hash类型是无序
 插入一批数据

for i in range(1000):
     conn.hset('hash_test','id_%s'%i,'鸡蛋_%s号'%i)

# res=conn.hgetall('hash_test')   # 可以,但是不好,一次性拿出,可能占很大内存
 print(res)
 13 hscan(name, cursor=0, match=None, count=None)   # 它不单独使用,拿的数据,不是特别准备
 res = conn.hscan('hash_test', cursor=0, count=5)
 print(len(res[1])) #(数字,拿出来的10条数据)   数字是下一个游标位置



# 咱们用这个,它内部用了hscan,等同于hgetall 所有数据都拿出来,count的作用是,生成器,每次拿count个个数
# 14 hscan_iter(name, match=None, count=None)
res=conn.hscan_iter('hash_test',count=10)
 print(res)  # generator 只要函数中有yield关键字,这个函数执行的结果就是生成器 ,生成器就是迭代器,可以被for循环
 for i in res:
#     print(i)
conn.close()


'''
hset
hget
hmget
hlen
hdel
hscan_iter  获取所有值,但是省内存 等同于hgetall
'''

redis其他操作

通用操作,不指定类型,所有类型都支持

  • delete(*names) 根据删除redis中的任意类型

  • exists(name) 检测redis的name是否存在

  • keys(pattern='*') 根据模型获取redis的name

# 更多:
    # KEYS * 匹配数据库中所有 key 。
    # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
    # KEYS h*llo 匹配 hllo 和 heeeeello 等。
    # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 
  • expire(name,time) 为某个redis的某个name设置超时时间

  • rename(src,dst) 对redis的name重命名为。。

  • move(name,db) 将redis的某个值移动到指定的db下

  • randomkey() 随机获取一个redis的name

  • type(name) 获取name对应的类型

import redis

conn = redis.Redis()
# 1 delete(*names)
# conn.delete('name', 'userinfo2')
# conn.delete(['name', 'userinfo2'])  # 不能用它
# conn.delete(*['name', 'userinfo2'])  # 可以用它


# 2 exists(name)
# res=conn.exists('userinfo')
# print(res)


# 3 keys(pattern='*')
# res=conn.keys('w?e')  #  ?表示一个字符,   * 表示多个字符
# print(res)


# 4 expire(name ,time)
# conn.expire('userinfo',3)

# 5 rename(src, dst)
# conn.rename('hobby','hobby111')

# 6 move(name, db))
# conn.move('hobby111',8)
# 7 randomkey()
# res=conn.randomkey()
# print(res)
# 8 type(name)
# print(conn.type('girls'))
print(conn.type('age'))
conn.close()

redis管道

# 事物 --->>> 四大特性
   原子性、一致性、隔离性、持久性

# redis支持事物吗 单实例才支持所谓的事物,支持事物是基于管道的
   执行命令		一条一条执行
 张三 金额 -100	conn.decr('张三_je', 100)
 报错
 你	金额	100		conn.incr('李四_je', 100)
 
把这两条命令,放到一个管道中,先不执行,执行excute,一次性都执行完
 conn.decr('张三_je', 100)	conn.incr('李四_je', 100)
 
 # 如何使用
 
import redis
conn = redis.Redis()
p = conn.pipline(transaction=True)  # 固定写法
p.multi() # 固定写法

p.decr('张三_je', 100)
raise Exception('崩了')  # 程序崩了,执行到张三_je它的金额也不会减少。通过管道来开启事物要么都成功,要么都失败。
p.incr('lisi_je', 100)

p.execute()
conn.close()

没有开启基于管道的事物:

image-20230308192931554

结果:

image-20230308193057696

redis支持事物,基于管道支持的。

之前执行命令的时候都是一条条执行的,

张三减了,而另一个没加

image-20230308105553501

由管道来支持事物,要么都成功,要么都是失败

image-20230308193349796

Django中使用redis

方式一:自定义包方案(通用的,不针对于框架,所有的框架都可以用)

	-第一步:写一个pool.py
    import redis
	POOL = redis.ConnectionPool(max_connections=100)
    -第二步:以后在使用的地方,直接导入使用即可
    conn = redis.Redis(connection_pool=POOL)
    conn.incr('count')
    res = conn.get('count')

自定义包方案(所有包都可以使用)

测试:

image-20230308111705758

image-20230308111900797

image-20230308203347373

它是独立的,即使停了,再每运行一次增1

方式二:Django方案

方案一(推荐使用):Django的缓存使用redis

settings.py 中配置
	        CACHES = {
            "default": {
                "BACKEND": "django_redis.cache.RedisCache",
                "LOCATION": "redis://127.0.0.1:6379",
                "OPTIONS": {
                    "CLIENT_CLASS": "django_redis.client.DefaultClient",
                    "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                    # "PASSWORD": "123",
                }
            }
        }
  								res = cache.get('count')
  在使用redis的地方:cache.set('count', res+1)
  pickle序列化后,存入的

不写使用就是默认的内存cache,如图就是默认的,使用内存。

image-20230308112251412

将如上图中复制带配置文件中,改成改成django_redis.cache.RedisCache

image-20230308195607214

Django原生是不支持redis的,需要借助于第三方。pip install django-redis

image-20230308195043459

RedisCache源码

image-20230308195935697

image-20230308200406574

在Django中使用redis作为缓存

image-20230308112741025

image-20230308112751169

由于缓存没有自增。所以得取出来再加上

image-20230308112824635

这里需要区别于在redis中的count,在与Django中的count是不起冲突的。不用担心冲突

image-20230308112845607

pickle序列化后存入的

方案二:借助于第三方 Django-redis

(想实现方式一的,正常的redis导入使用)

    	from django_redis import get_redis_connection
        def test_redis(request):
            conn=get_redis_connection()
            print(conn.get('count'))
            return JsonResponse({'count': '今天这个接口被访问的次数为:%s'}, json_dumps_params={'ensure_ascii': False})

image-20230308211912424

posted @   小福福  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
  1. 1 原来你也在这儿 温余福
  2. 2 世间美好和你环环扣扣 温余福
  3. 3 随风起舞 温余福
  4. 4 罪恶都市 温余福
罪恶都市 - 温余福
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 王星

作曲 : 灰鸿啊/皮皮

编曲 : 夏日入侵企画

制作人 : 邢硕

节奏吉他 : 肯尼

主音吉他 : 张伟楠

贝斯 : 皮皮

鼓 : 海鑫

和声 : 邢硕

音效制作 : 邢硕

录音 : 邢硕/夏国兴

混音 : 于昊

特别鸣谢 : 张伟楠

这城市的车流和这地表的颤抖

像一颗石子落入地心之后泛起的温柔

暗涌

河水流过转角她的楼

被梦魇

轻声呓语唤醒身后的幼兽

失效感官焦灼只剩下

麻木愚钝无从感受

共同支撑全都瓦解

只是我们现在都

已忘记到底是

谁隐藏春秋

谁在大雨之后

把旗帜插在最高的楼

过去陈旧的还在坚守

内心已腐朽

摇摇欲坠不停退后

毁灭即拯救

夏日掠夺春秋

结局无法看透

眼看这情节开始变旧

所有的城池已失守

最终无法占有

无眠辗转

伴着人间破碎的旧梦

像繁星

退却后只剩下混沌的夜空

炙热

掩盖风声鹤唳的担忧

把所有失落无助反手推入

无尽的白昼

失效感官焦灼只剩下

麻木愚钝无从感受

共同支撑全都瓦解

只是我们现在都已经忘记到底是

谁隐藏春秋

谁在大雨之后

把旗帜插在最高的楼

过去的陈旧还在坚守

内心已腐朽

摇摇欲坠不停退后

毁灭即拯救

夏日掠夺春秋

结局无法看透

眼看这情节开始变旧

所有的城池早已失守

惶恐难以接受

缠绵往复不肯放手

最终无法占有

谁隐藏春秋

谁在大雨之后

把旗帜插在最高的楼

过去的陈旧还在坚守

内心已腐朽

摇摇欲坠不停退后

毁 灭 即 拯 救

谁掠夺春秋

谁在大雨之后

把旗帜插在最高的楼

过去的陈旧还在坚守

内心已腐朽

摇摇欲坠不停退后

毁灭即拯救

夏日掠夺春秋

结局无法看透

明知城池已失守

缠绵往复不肯放手

最终无法占有

点击右上角即可分享
微信分享提示