Redis哈希类型详解:从基础命令到实际应用

news/2024/9/28 23:01:04 标签: 哈希算法, 算法, redis, windows, 缓存, 数据库

引言

前边介绍了 Redis 中字符串类型,现在接上篇文章继续学习 Redis 哈希类型的命令和实际应用

哈希(Hash)类型是一种非常实用的数据结构,以字段-值对的形式存储多个键值对。这里将详细介绍 Redis 哈希类型的使用方法、内部编码以及在实际开发中的应用场景


1. 什么是哈希类型?

哈希类型在 Redis 中是一种特殊的键值对结构,它的值本身又是一个键值对集合。你可以把它想象成一个小型的数据库表,其中每个键代表一条记录,而每条记录包含多个 field 和对应的 value。

例如:

  • user:1 可以作为一个键,表示用户ID为1的信息。
  • 在这个键下,可以有多个字段如 nameagecity 等,每个字段都有对应的值。

2. 基本命令详解

1. 设置和获取字段
  • HSET - 设置或更新哈希表中指定字段的值。

    HSET user:1 name "James" age 28 city "Beijing"

    如果字段已经存在,HSET 会更新其值;如果字段不存在,则创建新的字段并设置值。

  • HGET - 获取哈希表中指定字段的值。

    HGET user:1 name

    返回指定字段的值,如果字段不存在则返回 nil

2. 检查字段是否存在
  • HEXISTS - 检查给定字段是否存在于哈希表中。
    HEXISTS user:1 gender
    返回 1 表示字段存在,0 表示字段不存在。
3. 删除字段
  • HDEL - 从哈希表中删除一个或多个字段。
    HDEL user:1 city
    返回成功删除的字段数量。
4. 查看所有字段和值
  • HKEYS - 获取哈希表中的所有字段名。

    HKEYS user:1

    返回所有字段名的列表。

  • HVALS - 获取哈希表中的所有字段值。

    HVALS user:1

    返回所有字段值的列表。

  • HGETALL - 获取哈希表中所有的字段及其对应的值。

    HGETALL user:1

    返回所有字段和对应值的列表,格式为 [field1, value1, field2, value2, ...]

5. 批量操作
  • HMGET - 获取哈希表中多个字段的值。

    HMGET user:1 name age

    返回指定字段的值列表,不存在的字段返回 nil

  • HMSET - 设置哈希表中多个字段的值。(注意:从 Redis 4.0 开始,推荐使用 HSET 代替 HMSET

    HMSET user:1 name "John" age 29
6. 字段计数
  • HLEN - 获取哈希表中字段的数量。
    HLEN user:1
    返回哈希表中字段的总数。
7. 自增操作
  • HINCRBY - 将哈希表中字段的整数值增加指定数量。

    HINCRBY user:1 score 10

    返回增加后的值。

  • HINCRBYFLOAT - 将哈希表中字段的浮点数值增加指定数量。

    HINCRBYFLOAT user:1 score 10.5

    返回增加后的值。


3. 内部编码

Redis 会根据哈希表中元素的数量和大小自动选择最合适的内部编码来优化内存使用和性能:

  • ziplist(压缩列表) - 当哈希表中的元素较少且每个值都不大时,Redis 会选择 ziplist 作为内部编码。这种方式占用更少的内存,并且对于小数据集具有较高的性能。

    • 默认配置:hash-max-ziplist-entries = 512 和 hash-max-ziplist-value = 64 字节。
  • hashtable(哈希表) - 当哈希表中的元素较多或者某个值较大时,Redis 会切换到 hashtable,以保证高效的读写操作。

    • 这种方式在处理大数据集时更加高效,时间复杂度为 O(1)。

可以通过 OBJECT ENCODING 命令查看特定键的内部编码方式:

OBJECT ENCODING user:1

ziplist

hashtable

4. 使用场景

哈希类型非常适合用来缓存用户信息等实体对象。相比于直接使用字符串序列化整个对象,哈希类型提供了更细粒度的操作能力,比如单独更新用户的某一个属性而不必重新序列化整个对象。

示例代码

以下是一个使用 Java 伪代码示例,展示如何利用哈希类型来实现用户信息的缓存

public class UserService {
    private final Jedis jedis; // 假设使用 Jedis 客户端

    public UserService(Jedis jedis) {
        this.jedis = jedis;
    }

    public UserInfo getUserInfo(long uid) {
        // 构建 Redis 键
        String key = "user:" + uid;

        // 从 Redis 中尝试获取用户信息
        Map<String, String> userInfoMap = jedis.hgetAll(key);

        // 如果缓存命中
        if (userInfoMap != null && !userInfoMap.isEmpty()) {
            // 构建并返回用户信息对象
            return new UserInfo(
                userInfoMap.get("name"),
                Integer.parseInt(userInfoMap.get("age")),
                userInfoMap.get("city")
            );
        }

        // 缓存未命中,从数据库中获取
        UserInfo userInfo = database.getUserById(uid);

        // 如果数据库中没有该用户
        if (userInfo == null) {
            // 返回 404 错误
            throw new NotFoundException("User not found");
        }

        // 将用户信息保存到 Redis,并设置过期时间
        Map<String, String> fields = new HashMap<>();
        fields.put("name", userInfo.getName());
        fields.put("age", String.valueOf(userInfo.getAge()));
        fields.put("city", userInfo.getCity());
        jedis.hmset(key, fields);
        jedis.expire(key, 3600); // 设置过期时间为 1 小时

        // 返回用户信息
        return userInfo;
    }
}

5. 缓存方式对比

  1. 原生字符串类型 - 每个属性一个独立的键。简单但可能导致大量键不好管理,而且内存占用较高。

    SET user:1:name "James"
    SET user:1:age 23
    SET user:1:city "Beijing"

    优点:实现简单,针对个别属性变更也很灵活。

    缺点:占用了过多的键,内存占用量较大,同时用户信息在 Redis 中比较分散,低内聚。

  2. 序列化字符串类型 - 如 JSON 格式,适合整体操作,但在处理局部更新时效率较低。

    SET user:1 "{
                   \"name\":\"James\",
                   \"age\":23,
                   \"city\":\"Beijing\"
                }"

    优点:针对总是以整体作为操作的信息比较合适,编程也简单。同时,如果序列化方案选择合适,内存的使用效率很高。

    缺点:本身序列化和反序列需要一定开销,同时如果总是操作个别属性则非常不灵活。

  3. 哈希类型 - 结合了前两者的优点,既灵活又高效,特别适用于需要频繁更新单个属性的场景。

    HMSET user:1 name "James" age 23 city "Beijing"

    优点:简单、直观、灵活。尤其是针对信息的局部变更或者获取操作。

    缺点:需要控制哈希在 ziplist 和 hashtable 两种内部编码的转换,可能会造成内存的较大消耗。


结论

以上就是 Redis 中哈希类型相关的知识,后续会继续更新,感谢阅览!!


http://www.niftyadmin.cn/n/5682019.html

相关文章

【RocketMQ】RocketMQ快速入门

&#x1f3af; 导读&#xff1a;该文档介绍了Apache RocketMQ消息队列的基础应用&#xff0c;包括消息发送与接收的基本流程。首先通过创建生产者实例&#xff0c;并指定名称服务器地址&#xff0c;启动后即可发送消息至指定主题。然后创建消费者实例订阅相应主题&#xff0c;并…

MATLAB数据文件读写:2.矩阵数据读取

矩阵数据读取 写入文件–save函数 保存变量到文件中&#xff0c;用于以后使用。 save(fielname) 将当前工作区中所有变量保存到matlab格式的二进制文件filename中。: .mat save(filename, ‘var’,fmt) 将当前工作区中var指定的结构体数组的变量或字段保存到matlab格式的…

线上报名小程序怎么做

在这个数字化、智能化的时代&#xff0c;信息技术的发展正以前所未有的速度改变着我们的生活。无论是学习、工作还是娱乐&#xff0c;互联网都成为了我们不可或缺的一部分。而在线上报名这一领域&#xff0c;小程序的出现更是为广大用户带来了前所未有的便捷与高效。今天&#…

用大模型 vs 垂直大模型

人工智能&#xff08;AI&#xff09;大模型的发展已经进入了一个新的战场&#xff0c;主要分为通用大模型和垂直大模型两个方向。通用大模型因其广泛的应用场景和普适性备受关注&#xff0c;而垂直大模型则因其在特定领域内的高效性和专业性逐渐崭露头角。随着技术的不断演进&a…

基于Node.js+Express+MySQL+VUE实现的在线电影视频点播网站管理系统的设计与实现部署安装

目录 1. 引言 1.1开发背景 1.2开发意义 1.3国内外研究 2. 需求分析 3. 系统架构设计 4. 关键技术选型 5. 功能模块设计 5.1功能图 5.2界面介绍 6. 总结 1. 引言 随着互联网技术的快速发展和普及&#xff0c;人们获取信息的方式发生了巨大变化&#xff0c;其中在…

AI周报(9.22-9.28)

AI应用-Siipet宠物沟通师 Siipet是一款由SiiPet公司推出的创新宠物行为分析相机&#xff0c;旨在通过尖端技术加深宠物与主人之间的情感联系。这款相机利用先进的AI算法&#xff0c;能够自动识别和分析家中宠物的行为&#xff0c;并提供定制化的护理建议。 SiiPet相机的核心功…

iOS 小组件

基本知识 时间轴 小组件通过AppIntentTimelineProvider进行 UI 刷新 struct Provider: AppIntentTimelineProvider {func placeholder(in context: Context) -> SimpleEntry {// 添加占位的&#xff08;选择添加的时候使用&#xff09;// todo}func snapshot(for configu…

Goland的使用

一、安装Goland 一、Goland简介 Goland是由JetBrains公司旨在为go开发者提供的一个符合人体工程学的新的商业IDE。这个IDE整合了IntelliJ平台的有关go语言的编码辅助功能和工具集成特点 二、下载相应的安装包 1、官网下载地址 GoLand by JetBrains: More than just a Go IDE 三…