redis哈希类型

  • 数据形式
  • 哈希特点
  • 常用命令
  • 哈希应用场景
  • 哈希应用于缓存


数据形式

redis hash和字符串性能_redis hash和字符串性能

  1. 哈希内部为 --字段:值,键值对,最多redis hash和字符串性能_redis_02个键值对
  2. 字段,值 必须都为字符串,采用压缩列表存储,节约内存

哈希特点

  1. 按需取字段,读取速度快
  2. 键过期,内部字段全部过期
  3. 存储消耗内存大于字符串结构

常用命令

  1. 添加哈希类型的数据
    #添加一个字段
#添加一个字段
hset  user:1  name jack
得到{"name":"jack"}
python中添加,r为连接对象
r.hset("user:1","name","jack")
#添加多个字段
#添加多个字段
hmset  user:1  name jack age 23 addr China hobby pingpong
得到{"name":"jack",“age”:"23","addr":"China","hobby":"pingpong"}
python中实现
r.hmset("user:1",{"name":"jack","age":23,"addr":"China","hobby":"pingpong"})
  1. 读取哈希字段
#读取一个字段name
hget  user:1  name 
#读取多个字段
hmget user:1 name age addr
python中,
r.hget("user:1","name")
r.hmget("user:1","name","age")
  1. key不存在时,再添加哈希数据,若存在当前key,则什么也不做
hsetnx  user:1  name jack age 23 addr China hobby pingpong
  1. 统计键值对数
hlen  user:1
  1. 判断name字段是否存在
hexists  user:1  name

6.获取所有键值对

hgetall  user:1
python中获取所有键值对
import redis
#从其他主机连接redis-server,需要配置远程连接
r=redis.Redis(host="192.168.245.142",port=6379,password="xxx",db=0)
#返回python字典,无数据返回空字典
dict_=r.hgetall("user:1")
#此时dict_中的key,value 均为字节串,需转为字符串
dict1={key.decode():value.decode() for key,value in dict_.items()}
  1. 获取所有字段/值
hkeys  user:1 
hvals  user:1
python中返回字段/值列表
key_list=r.hkeys("user:1")
val_list=r.hvals("user:1")
  1. 其他
    删除一个字段name
    hdel user:1 name
    给数值字段增加一个值
    hincrby user:1 age 5
    hincrbyfloat user:1 score 2.3

哈希应用场景

  1. 用户多维度数据统计
  2. 缓存

哈希应用于缓存

创建一个django web项目:

  1. 请求路由1:/user/info/id,这里的id是可变的用户id,唯一标识一个用户。
    主路由匹配到user/,就转到应用user,在user的分布式路由中继续匹配,然后执行show_info视图函数,查询当前id的用户信息,优先走缓存,缓存没有则走mysql数据库,并把查询mysql的数据放入缓存一份,最后渲染一个用户信息的页面,返回
  2. 请求路由2:/user/info/update,
    以GET方式请求,返回一个表单页面,用于用户更新信息;
    以POST方式请求,则处理用户提交的信息,更新数据库,并删缓存

python实现:
django version 2.2.12

  1. 创建项目
django-admin startproject test_hash
  1. 配置项目
    test_hash/test_hash/settings.py
#配置mysql数据库,需要先创建test_hash数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "test_hash",
        "HOST":"192.168.245.149",
        "PORT":"3306",
        "USER":"lauf",
        "PASSWORD":"lauf123",
    }
}

#配置语言及时区
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
  1. ORM迁移
#生成迁移文件
python3 manage.py makemigrations
#迁移到数据库
python3 manage.py migrate
#启动django服务,测试
python3 manage.py runserver
-->浏览器访问127.0.0.1:8000

配置没有问题的话,会正常显示页面

  1. 创建user应用
python3  manage.py startapp user

#在settings.py中注册应用
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "user",
]

#在user/models.py
#创建模型类
from django.db import models
# Create your models here.
class User(models.Model):
    
    uname=models.CharField("用户名",max_length=30)
    description=models.TextField(max_length=100)
    
    def __str__(self):
        return self.uname
    #更改表名
    class Meta:
        db_table="user_table"

#迁移ORM
python3 manage.py makemigrations
python3 manage.py migrate

#进入django shell,创建两条数据
python3 manage.py shell

from user.models import User
names=["jack","tom"]
desc=["good boy","bad boy"]
for name,d in zip(names,desc):
	u=User(uname=name,description=d)
	u.save()

#可进入mysql,查看创建的数据
sudo mysql -u lauf -p
mysql>show databases;
mysql>use test_hash;
mysql>show tables;
mysql>select * from user_table;
+----+-------+--------------+
| id | uname | description  |
+----+-------+--------------+
|  1 | jack  | good student |
|  2 | tom   | bad boy      |
+----+-------+--------------+
  1. 配置路由
    路由1:/user/info/
    路由2:/user/info/update
    主路由中:test_hash/test_hash/urls.py
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("user/",include("user.urls")),
]
user应用中路由:user/urls.py   这里需要添加一个urls.py文件
from django.urls import path
from .views import show_info,update_info

urlpatterns=[
    path("info/<int:uid>",show_info),
    path("info/update",update_info),
]
#这里匹配到相应的路由,会执行相应的视图函数
  1. 定义视图函数
    在user应用中views.py,定义show_info,update_info函数
from django.http import HttpResponse
from django.shortcuts import render
import redis
from .models import User
import time
r=redis.Redis(host="192.168.245.149",port=6379,db=0)
# Create your views here.
def show_info(request,uid):
    """根据id查询是用户的数据
        优先走缓存,缓存没有再走数据库
        从数据库查询到数据放入缓存一份,然后渲染页面
    """
    #redis
    user=r.hgetall(uid)
    #no data  return {}
    if not user :
        print("走数据库")
        #模拟数据库的延时
        time.sleep(2)
        #mysql
        try:
            user=User.objects.get(id=int(uid))
            uname=user.uname
            description=user.description

        except:
            uname="No"
            description="No this user"

        data = {"uname": uname, "desc": description}
        # 放入缓存一份
        r.hmset(uid,data)
        r.expire(uid,20)

    else:
        print("走缓存")
        #使用缓存中的数据
        data={key.decode():value.decode() for key,value in user.items()}

    print(data)
    # 渲染页面
    return render(request, "user/show_info.html",data)

def update_info(request):
    """用户更新信息"""
    if request.method=="GET":

        return render(request,"user/update_info.html")

    elif request.method=="POST":
        uid=request.POST.get("uid")
        uname=request.POST.get("uname")
        description=request.POST.get("desc")

        #查询数据库中的用户
        try:
            #更新数据库
            user=User.objects.get(id=int(uid))
            user.uname=uname
            user.description=description

            user.save()
            #清空缓存
            r.delete(uid)
            return HttpResponse("更新OK")
        except:
            #未查询到该用户
            return HttpResponse("用户不存在")

    else:
        pass
  1. 定义模板
    在user应用下添加文件
    templates/user/show_info.html
    templates/user/update_info.html

show_info.html

<body>
    <p>个人主页</p>
    <label for="">用户名:</label>{{uname}}
    <br>
    <label for="">个人描述:</label>{{desc}}
</body>

update_info.html

<body>
    <form action="/user/info/update" method="post">
        {% csrf_token %}
        <label for="">用户id:</label><br>
        <input type="text" name="uid"><br>
        <label for="">用户名:</label><br>
        <input type="text" name="uname"><br>
        <label for="">个人描述:</label><br>
        <input type="text" name="desc"><br>
        <input type="submit" value="提交"><br>
    </form>
</body>

项目的整体代码:https://pan.baidu.com/s/1PnHA0Ww4m6nlgQrw_J6M0g 提取码:cxd0