redis 基础1(包含介绍,安装)

Redis介绍安装

复制代码
# 关于redis
    -1.redis是一个缓存型数据库【大部分时间做缓存,但是不仅仅可以做缓存】
    -2.redis是一个非关系型(nosql)数据库【区别于mysql】
    -3.redis是c语言写的服务,用来存储数据,数据是存储到内存中,取值,放值速度非常快,10w qps

# 面试题:redis为什么这么快
    -1.纯内存操作
    -2.网络模型使用的IO多路复用(epoll)(可以处理的请求数更多)
    -3.6.x之前,单进程,单线程架构,没有鲜葱进程间切换,更少的消耗资源
# redis使用 key-value的形式存储,没有表的概念

# 版本问题
   最新的:7.x
   公司里:5.x比较多

# 安装
   - mac    源码编译安装
   - linux   源码编译安装
   - win     微软自己,基于源码改动编译为安装包
             5.x 版本:https://github.com/tporadowski/redis/releases/
             3.x 版本:https://github.com/microsoftarchive/redis/releases
   - 一路下一步即可,安装完cmd执行两个命令,把redis自动添加到服务中
             redis-server    服务端的启动命令    mysqld
             redis-cli       客户端的启动命令    mysql
# 安装后的目录
   redis-server
   redis-cli
   redis.window-service.conf         配置文件
        -bind 127.0.0.1      # 服务跑的地址
        -port 6379           # 监听的端口

# 启动redis
   1.方式一:
        -在服务中,点击启动,后台启动
   2.方式二:
        -redis-server 指定配置文件,不指定会按默认的

# 客户端连接redis
   1.方式一
        -redis-cli          # 默认连接本地的6379端口
   2.方式二
        -redis-cli -h 地址 -p 端口
   3.方式三
        - 使用图形化客户端操作
         -1.Redis Desktop Manager:  
开源,现在收费,老版本免费(推荐)
-> 底层使用Qt5,qt是个平台,专门用来图形化界面的 -> 可以使用c++-> 可以使用python写 pyqt5 使用python写图形化界面 (少量公司再用) -2.Redis Client:
小众
- 图形化界面,连接redis 输入地址和端口,点击连接即可 # redis默认有16个库,默认连进去就是第0个
复制代码

Redis普通连接和连接池

# python 相当于客户端,操作redis
# 安装模块: pip install redis
# 补充: django中操作mysql,没有连接池的,一个请求就是一个mysql连接
  - 可能存在问题
      并发数过高,可能导致mysq'l连接数过高,进而影响mysql性能
  - 使用django连接池:
      https://blog.51cto.com/liangdongchang/5140039

普通连接

复制代码
# 1.安装redis模块
    pip install redis
# 2.导入模块的Redis类
    from redis import Redis
# 3.实例化得到对象
    coon =Redis(host='127.0.0.1',port=6379)
# 4.使用conn,操作redis
    - 获取name的值
      ->res=conn.get('name')     # 返回的数据是bytes格式
# 5.设置值
    conn.set('age',19)
    conn.close()
复制代码

连接池连接

复制代码
###1.创建一个pool.py
    import redis
    # 创建一个大小为10的redis连接池
    POOL = redis.ConnectionPool(max_connections=10,host='127.0.0.1',port=6379)   
###2.测试代码
    import redis
    from threading import Thread
    from pool import POOL
    def task():
         # 做成模块后,导入,无论导入多少次,导入的都是那一个POOL对象
         conn = redis.Redis(connection_pool=POOL)
         # 报错的原因是拿连接,连接池里不够了,没有等待,线程会报错,需要设置等待,参数
         print(conn.get('name'))
    for i in range(10000):
         # 每次都是一个新的连接,会导致连接池的连接数过多
         t=Thread(target=task)
         t.start()



### 单例模式
 -1.单例模式是一种设计模式【设计模式共有23种】
     - 全局只有一个 这个对象
          p1=Person()    # p1 对象
          p2=Person()    # p2 新对象
     - 单例模式的六种方式...
         
复制代码

Redis字符串类型

复制代码
# 1.redis 是key-value形式存储
# 2.redis 数据放在内存中,如果断电,数据丢失
      - 需要有持久化的方案

# 3.redis有5种数据类型【value类型】
      - 字符串:用的最多,做缓存;做计数器
      - 列表: 简单的消息队列
      - 字典(hash):缓存
      - 集合:去重
      - 有序集合:排行榜
        
#字符串类型使用
复制代码
'''
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)
'''

import redis

conn = redis.Redis()

# 1 set(name, value, ex=None, px=None, nx=False, xx=False)
# ex,过期时间(秒)
# px,过期时间(毫秒)
# nx,如果设置为True,则只有name不存在时,当前set操作才执行, 值存在,就修改不了,执行没效果
# xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
# conn.set('hobby','篮球',ex=3)
# conn.set('hobby','篮球',px=3)
# conn.set('name','lqz',nx=True)
# conn.set('name','lqz',nx=False)
# conn.set('hobby','篮球',xx=True)
# conn.set('hobby','篮球',xx=False)
# redis---》实现分布式锁,底层基于nx实现的


# 2 setnx(name, value)
# 等同于:conn.set('name','lqz',nx=True)
# conn.setnx('name', '刘亦菲')

# 3 setex(name, value, time)
# 等同于:conn.set('name','lqz',ex=3)
# conn.setex('wife', 3, '刘亦菲')


# 4 psetex(name, time_ms, value)
# conn.psetex('wife',3000,'刘亦菲')


# 5 mset(*args, **kwargs)
# conn.mset({'wife': '刘亦菲', 'hobby': '篮球'})


# 6 get(name)
# print(str(conn.get('wife'),encoding='utf-8'))
# print(conn.get('wife'))


# 7 mget(keys, *args)
# res=conn.mget('wife','hobby')
# res=conn.mget(['wife','hobby'])
# print(res)


# 8 getset(name, value)
# res=str(conn.getset('wife','迪丽热巴'),encoding='utf-8')
# res=conn.getset('wife','迪丽热巴')
# print(res)


# 9 getrange(key, start, end)
# res = str(conn.getrange('wife', 0, 2), encoding='utf-8')  # 字节长度,不是字符长度  前闭后闭区间
# print(res)


# 10 setrange(name, offset, value)
# conn.setrange('wife',2,'bbb')

# ---- 比特位---操作
# 11 setbit(name, offset, value)
# 12 getbit(name, offset)
# 13 bitcount(key, start=None, end=None)
# ---- 比特位---操作

# 14 bitop(operation, dest, *keys)   获取多个值,并将值做位运算,将最后的结果保存至新的name对应的值

# 15 strlen(name)
# res=conn.strlen('hobby')   # 统计字节长度
# print(res)

# 16 incr(self, name, amount=1)
# 自增,不会出并发安全问题,单线程架构,并发量高
# conn.incr('age')
# # incrby

# 17 incrbyfloat(self, name, amount=1.0) # conn.incrbyfloat('age',1.2) # 18 decr(self, name, amount=1) # conn.decrby('age') # conn.decrby('age',-1) # 19 append(key, value) # conn.append('hobby','sb') print(conn.strlen('hobby')) conn.close() ''' 重要的: set get strlen 字节长度 incr '''
复制代码
复制代码

Redis列表类型

复制代码
"""
1. lpush(name,values)
2. rpush(name,values)         # 表示从右向左操作
3. lpush(name,values)
4. rpushx(name,values)        # 表示从右向左操作
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.linedx(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(host='127.0.0.1',port=6379)
复制代码
# 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)
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)  # 按位置改值
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()
## 重要的
'''
1. lpush
2. lpop
3. llen
4. lrange
'''
复制代码
复制代码

Redis之hash类型

复制代码
"""
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. vals(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(host='127.0.0.1',port=6379)
复制代码
# 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()

'''

1.hset

2.hget

3.hmget

4.hlen

5.hdel

6.hscan_iter 获取所有值,但是省内存 等同于hgetall

'''

复制代码

Redis其他操作

复制代码
''' 
通用操作,不指定类型,所有类型都支持
 1.delete(*names)
 2.exists(name)
 3.keys(pattern='*')
 4.expire(name ,time)
 5.rename(src, dst)
 6.move(name, db))
 7.randomkey()
 8.type(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('zhangsan_je',100)
       程序中途挂了
       raise("挂了")
       你   金额并没有+100     
       conn.incr('lisi_je',100)
       """
     - 把这两条命令,放到一个管道中,先不执行,执行excute,一次性都执行完成
       """
       conn.decr('zhangsan_je',100)   
       conn.incr('李四_je',100)
       """
# 使用方法:
import redis
conn = redis.Redis()
p=conn.pipeline(transaction=True)
p.multi()
p.decr('zhangsan_je', 100)
# raise Exception('崩了')
p.incr('lisi_je', 100)

p.execute()
conn.close()
复制代码

 

 

 

posted @   橘子菌菌n  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示