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",
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/gwklan/p/11302282.html