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",
            }
        }
    }
  • 相关阅读:
    UVA
    UVA
    模板——扩展欧几里得算法(求ax+by=gcd的解)
    UVA
    模板——2.2 素数筛选和合数分解
    模板——素数筛选
    Educational Codeforces Round 46 (Rated for Div. 2)
    Educational Codeforces Round 46 (Rated for Div. 2) E. We Need More Bosses
    Educational Codeforces Round 46 (Rated for Div. 2) D. Yet Another Problem On a Subsequence
    Educational Codeforces Round 46 (Rated for Div. 2) C. Covered Points Count
  • 原文地址:https://www.cnblogs.com/gwklan/p/11302282.html
Copyright © 2011-2022 走看看