zoukankan      html  css  js  c++  java
  • Redis内存数据库的基本语法

    Redis:

      - nosql数据库,非关系型数据库

      - 支持5大数据类型 (字符串String,列表list、字典hash,集合set,zset)

        - 与之相似的有memcache,但memcache只支持string类型

      - 单进程单线程,好处在于不用考虑并发

    Redis常用操作

     from redis import Redis# from redis import ConnectionPool

    conn = Redis()  # 实例化对象,创建连接对象
    
    # conn.set('name','dxx')  # 单个插入
    
    # for i in range(1,100):
    #     conn.set("the %s key"%i, 'the %s value'%i,ex=i)  # 循环插入
    
    
    # ret = conn.get("the 80 key")  # 取不到是为None  无法指定默认值
    #
    # print(ret)
    
    # conn.set('name','希希')  # 单个插入 中文会自动以utf8编码转码为bytes类型
    
    #
    # for i in range(1,100):
    #     conn.set("%skey"%i,'%svalue'%i)
    
    from app01.Redis_POOL import POOL   # 连接池做成单例
    conn = Redis(connection_pool=POOL)
    
    
    
     print(conn.get("name").decode("utf8"))
    
    # 字符串操作
     conn.set('age',19,ex=10,xx=True)
    
    
     conn.setex('hobby',10,'basketball') # (key,time, value)
    
    # 批量添加,传字典
    conn.mset({'k1':'v1','k2':'v2'})
    
    # 批量取值
     print([ res.decode("utf8") for res in conn.mget(['k1', 'k2'])])
    
    # 追加
     conn.setrange('k1',1,'pp')  # 从索引1的位置往后覆盖
    
     conn.set('k3','10')
    #
     conn.setrange('k3',2,'10')  # 从索引2的位置往后覆盖
    # #
     print(conn.get('k3'))
    
    
    # 重点 (网站访问量)
    
     conn.incr('ask_total',amount=1)  # 递增   可指定频率为负数,表示递减
     conn.decr('ask_total')   # 与上相反
    
    
     conn.append('ask_total',22)   # 向原有值后拼接
    
    
    #hash操作
    
     conn.hset('hax1','k1','v1')  #
     print(conn.hget("hax1", 'k1'))  #
    
    
    #批量存取
     conn.hmset('hax1',{'k2':'v2','k3':'v3'})
     print(conn.hmget('hax1', ['k1', 'k2',]))
     print(conn.hmget('hax1', 'k1', 'k2'))  # 内部做判断是否列表
    
    
     print(conn.hgetall('hax1'))   # {b'k1': b'v1', b'k2': b'v2', b'k3': b'v3'}
     print(conn.hgetall('hax1')[b"k1"])   # b'v1'
    
    
     print(conn.hlen('hax1'))  # 3   列表/数组长度
    
    
     conn.hdel('hax1','k1')    # 哈希删除
     print(conn.hget('hax1','k1'))  # 再查询
    
     conn.hset('hax1','k2',22)
     conn.hincrby('hax1','k2',amount=-10)  # 哈希递增 或者递减
     print(conn.hget('hax1','k2'))
    
    # 重点
     hscan
     hscan_iter
    
     for i in range(1,1000):
         conn.hset('hax2','%skey'%i,'%svalue'%i)
    
    # match 过滤条件 模糊匹配,只有?和*两种模式,?表示匹配一个,*表示匹配多个count 取出数据个数 
    
    print(conn.hscan('hax2',10,match='350value',count=20)) # (26, {}) 
    
    print(conn.hscan('hax2',10,match='350',count=20)) # (26, {}) 
    
    print(conn.hscan('hax2',10,match='350key',count=20)) # (26, {b'350key': b'350value'}) #  
    conn.hscan_iter('hax2',count=10) genrator = conn.hscan_iter('hax2',count=10) 
    
    # 产生迭代器,迭代器能产生的数据不因count值而变化, 
    # count的作用是限制一次向redis要多少数据,用完了再要 
    
    print(genrator) # 打印的生成器内存地址 
    
    print('生成器长度:',len(list(genrator))) # 会取完hax2中所有的数据 
    
    for i in genrator: 
      print(i) 
    
    # 由于上方len(list(genrator))已经将生成器迭代完,故迭代器已经无元素可迭代,无值打印 # redis列表操作  
    conn.lpush('h1','11') # 列表左追加  
    conn.rpush('h1','10','9') # 列表右追加 
    
    print(conn.linsert('h1','AFTER','11',99)) # 在元素11后面插入99 
    
    print(conn.linsert('h1','AFTER','11','99')) # 在元素11前面插入99 #如果列表中有多个'11',那么插在第一个'11'的前面或者后面 
    
    print(conn.llen('h1')) 
    
    conn.lset('h1',1,'1111') # 将索引为1的元素用'1111'替换 
    
    conn.lrem('h1',-5,11) 
    #lrem(name,count,value) 
    # count的正负表示从头开始还是从尾巴开始删除和value相同的值,0表示删除所有相同的 
    #count的数字表示删除几个 
    
    print(conn.lindex('h1', 3)) # 取列表索引为3的值 
    
    print(conn.lrange('h1', 1, 5)) #切片取值 取列表索引1-5的元素,闭区间 
    
    print(conn.lrange('h1',0,conn.llen('h1'))) # 取列表所有元素 
    
    
    #blpop 重点
    
    print(conn.lpop('h1')) 
    
    print(conn.lpop('h1')) # 从左删除一个元素 
    
    print(conn.rpop('h1')) # 从右删除一个元素 
    
    while True: 
      print(conn.blpop('h1')) # 取完了会在这里阻塞,等待有下一个值被添加,你会不会想到队列呢? 
                    # 是的,它可以实现队列的效果,可以实现分布式
                    # 可以同时开多个客户端去blpop,也可以同时开多个客户端去新增 
    # 自定义列表生成器
      - 如果列表非常庞大,一次性取出可能会撑爆内存,因此需要自定义列表生成器进行迭代取值
    
    def scan_list(name,count=10):
         index = 0
         while True:
             data_list = conn.lrange(name,index,count)
             if not data_list:
                 return
             index+= count
             count+=index
             for item in data_list:
                 yield item
    
     sa_list = scan_list('h1',5)
     for i in sa_list:
         print(i)
    
    
    conn.delete('name')   # 删除
    
    print(conn.exists('hax2'))   # 返回0或1
    
    
    print(conn.keys('k?'))   # 模糊匹配,只有?和*两种模式,?表示匹配一个,*表示匹配多个
    print(conn.keys('k*'))
    
    
     conn.rename('k1','kk')  # 重命名
    
    
    
    
    
    
    
    # 利用管道实现事务操作,redis没有自身事务操作,需借助管道实现
    pipe = conn.pipeline(transaction=True)   
    pipe.multi()
    pipe.set('name','egon')
    pipe.lpush('h1','aa')
    pipe.execute()

    应用场景:

    一、利用原生redis实现网站流量统计

    由于是全局统计,Django中我们需要自定义中间件来实现

    from redis import Redis
    from django.middleware.common import MiddlewareMixin
    
    Conn = Redis()
    class CountVisitorMiddle(MiddlewareMixin):
        def process_request(self,request):
            num = Conn.hget('count_visitor','number')
            if num:
                Conn.hset('count_visitor','number',int(num.decode("utf8"))+1)
            else:
                Conn.hset('count_visitor', 'number', 1)

    配置文件中配置:

    MIDDLEWARE = [
        .......其他中间件.........
        'app01.CountCustomerMiddleWare.CountVisitorMiddle',
    ]

    视图函数中使用:

    from django.shortcuts import render
    
    # Create your views here.
    
    from app01.redis_hander import Conn
    def index(request):
        visitor_number = Conn.hget('count_visitor','number').decode('utf8')
        return render(request,"index.html",locals())

    效果:

    当然,django有更好的封装来让我们使用基于redis的缓存实现

    二、利用Django基于redis的缓存实现网站流量统计

     配置文件中配置缓存信息:

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",   # cache存储引擎为redis数据库
            "LOCATION": "redis://127.0.0.1:6379",         # redis服务器地址
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}    # redis数据库连接池大小限制
                # "PASSWORD": "123",
            }
        }
    }
  • 相关阅读:
    bzoj2115: [Wc2011] Xor
    bzoj2844: albus就是要第一个出场
    hdu3949
    bzoj2487: Super Poker II
    bzoj3456: 城市规划
    bzoj3992: [SDOI2015]序列统计
    ubuntu 使用命令行登录oracle
    ubuntu安装docker
    linux查询硬件信息
    ubuntu oracle 环境搭建
  • 原文地址:https://www.cnblogs.com/gwklan/p/11302282.html
Copyright © 2011-2022 走看看