Redis--基础知识点--27--redis缓存分类树

在 Redis 中存储分类树,通常需要选择合适的数据结构来表现层级关系。以下是使用 字符串(String)哈希(Hash) 两种常见方案的举例说明,结合电商分类场景(如 电子产品 > 手机 > 智能手机 > 品牌)展开:


方案一:字符串(String)存储路径

数据结构设计
  • 键名category:path:{node_id}
    • 例如:category:path:1001
  • :完整分类路径(用分隔符连接)
    • 例如:电子产品>手机>智能手机>苹果
操作示例
  1. 添加分类

    # 添加根节点(电子产品)
    SET category:path:1001 "电子产品"# 添加子节点(手机)
    SET category:path:1002 "电子产品>手机"# 添加叶节点(苹果)
    SET category:path:1005 "电子产品>手机>智能手机>苹果"
    
  2. 查询分类

    # 获取苹果的完整路径
    GET category:path:1005  # 返回 "电子产品>手机>智能手机>苹果"# 查询所有手机相关分类(通过模式匹配)
    KEYS category:path:1002*  # 返回匹配的键(需谨慎使用 KEYS 命令)
    
  3. 删除分类

    # 删除苹果分类(需同时处理其子节点,此处假设无子节点)
    DEL category:path:1005
    
  4. 遍历分类树

    # 查询所有根节点(假设根节点路径不含 ">")
    SCAN 0 MATCH category:path:* COUNT 100  # 遍历所有键,过滤不含 ">" 的值
    
优缺点
  • 优点:实现简单,路径直观。
  • 缺点
    • 查询子节点需解析路径字符串(如通过 STRSPLIT 拆分 >)。
    • 更新路径需级联修改所有子节点(如重命名“手机”为“移动设备”,需更新所有子节点路径)。

方案二:哈希(Hash)存储层级关系

数据结构设计
  • 键名category:node:{node_id}
  • 字段
    • name: 分类名称
    • parent_id: 父节点 ID(根节点为 0nil
    • level: 层级深度(可选)
操作示例
  1. 添加分类

    # 添加根节点(电子产品)
    HSET category:node:1001 name "电子产品" parent_id 0 level 1# 添加子节点(手机)
    HSET category:node:1002 name "手机" parent_id 1001 level 2# 添加叶节点(苹果)
    HSET category:node:1005 name "苹果" parent_id 1003 level 4
    
  2. 查询分类

    # 获取苹果的父节点 ID
    HGET category:node:1005 parent_id  # 返回 "1003"# 查询手机的所有子节点(需递归查询)
    # 步骤1:找到手机的节点ID(假设为1002)
    # 步骤2:查询所有 parent_id=1002 的节点
    SCAN 0 MATCH category:node:* COUNT 100 | xargs -I{} redis-cli HGET {} parent_id | grep 1002
    
  3. 删除分类

    # 删除苹果分类(需同时删除其子节点,此处假设无子节点)
    DEL category:node:1005
    
  4. 遍历分类树

    # 查询所有根节点(parent_id=0)
    SCAN 0 MATCH category:node:* COUNT 100 | xargs -I{} redis-cli HGET {} parent_id | grep 0
    
优缺点
  • 优点
    • 结构清晰,便于查询父子关系。
    • 修改分类名称无需级联更新子节点(仅修改当前节点 name 字段)。
  • 缺点
    • 查询子节点需递归或多次访问 Redis。
    • 需维护 parent_idlevel 字段,增加数据一致性风险。

方案三:优化方案 - 路径枚举 + 哈希

结合两种方案优点,使用 哈希存储属性 + 字符串存储路径枚举

数据结构设计
  • 哈希category:node:{node_id} 存储 nameparent_id
  • 字符串category:path:{node_id} 存储完整路径(如 电子产品>手机>苹果)。
操作示例
  1. 添加分类

    # 添加苹果分类
    HSET category:node:1005 name "苹果" parent_id 1003
    SET category:path:1005 "电子产品>手机>智能手机>苹果"
    
  2. 查询路径

    # 获取苹果的完整路径
    GET category:path:1005
    
  3. 查询子节点

    # 通过哈希查询父节点 ID,再通过路径枚举匹配子节点
    HGET category:node:1003 parent_id  # 假设1003是智能手机的节点ID
    KEYS category:path:1003*  # 匹配所有以智能手机路径开头的节点
    
优缺点
  • 优点
    • 路径查询高效(直接通过字符串匹配)。
    • 属性修改灵活(通过哈希单独更新)。
  • 缺点
    • 数据冗余(同时存储哈希和字符串)。
    • 需维护两种数据结构的一致性。

方案四:使用 RedisJSON 存储树形结构

如果 Redis 版本支持 RedisJSON 模块,可直接存储 JSON 树形结构:

数据结构设计
  • 键名category:tree
  • :JSON 对象,例如:
    {"id": 1001,"name": "电子产品","children": [{"id": 1002,"name": "手机","children": [{"id": 1003,"name": "智能手机","children": [{"id": 1004, "name": "苹果"},{"id": 1005, "name": "华为"}]}]}]
    }
    
操作示例
  1. 添加分类

    JSON.SET category:tree . '{"id":1001,"name":"电子产品","children":[{"id":1002,"name":"手机","children":[]}]}'
    
  2. 查询子节点

    JSON.GET category:tree $.children[0].children  # 返回手机分类的子节点
    
  3. 更新分类

    JSON.SET category:tree $.children[0].children[0].name '移动设备'  # 重命名手机为移动设备
    
优缺点
  • 优点
    • 结构自然,支持嵌套查询。
    • 减少数据冗余(单个键存储完整树)。
  • 缺点
    • 需 Redis 版本 ≥ 4.0 且安装 RedisJSON 模块。
    • 修改深层节点需精确 JSON 路径(如 $.children[0].children[0].name)。

总结与选型建议

方案适用场景优点缺点
字符串路径简单分类树,查询需求少实现简单,路径直观更新路径需级联修改
哈希层级需频繁查询父子关系结构清晰,修改灵活查询子节点需递归
路径枚举+哈希平衡路径查询与属性修改路径查询高效,属性修改灵活数据冗余,维护复杂
RedisJSON 树形复杂分类树,需嵌套查询结构自然,支持复杂操作依赖模块,路径操作复杂

推荐方案

  • 简单场景:使用 字符串路径哈希层级
  • 中等复杂度:使用 路径枚举+哈希
  • 复杂场景:使用 RedisJSON 树形(需确保环境支持)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80043.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】汇编角度分析栈攻击

栈攻击 介绍原理示例代码汇编分析 介绍原理 核心原理是通过 缓冲区溢出(Buffer Overflow) 等漏洞,覆盖栈上的关键数据(如返回地址、函数指针),从而改变程序执行流程; 在 C 中,每个…

访问 Docker 官方镜像源(包括代理)全部被“重置连接”或超时

华为云轻量应用服务器(Ubuntu 系统) 遇到的问题是: 🔒 访问 Docker 官方镜像源(包括代理)全部被“重置连接”或超时了,说明你这台服务器的出境网络对这些国外域名限制很严格,常见于华…

Java语言

本文来源 : 腾讯元宝 Java是一种面向对象、跨平台的高级编程语言,最初由Sun Microsystems(现为Oracle公司所有)于1995年推出,广泛应用于Web开发、移动应用、大数据处理、嵌入式系统等领域。以下是其核心特点和应用概述…

无偿帮写毕业论文(看不懂的可以私信博主)

以下教程教你如何利用相关网站和AI免费帮你写一个毕业论文。毕竟毕业论文只要过就行,脱产学习这么多年,终于熬出头了,完成毕设后有空就去多看看亲人好友,祝好! 一、找一个论文模板 废话不多说,先上干货Ov…

python打卡day26

函数、参数、变量 知识点回顾: 函数的定义变量作用域:局部变量和全局变量函数的参数类型:位置参数、默认参数、不定参数传递参数的手段:关键词参数传递参数的顺序:同时出现三种参数类型时 def function_name(parameter…

LeetCode 热题 100 437. 路径总和 III

LeetCode 热题 100 | 437. 路径总和 III 大家好,今天我们来解决一道经典的二叉树问题——路径总和 III。这道题在 LeetCode 上被标记为中等难度,要求计算二叉树中节点值之和等于给定目标值 targetSum 的路径数目。 问题描述 给定一个二叉树的根节点 ro…

vue3学习-局部使用vue框架案例

目录 局部使用vue框架步骤 简单案例1 简单案例2【 结构化赋值语法】 简单案例3【使用模块化开发模式】 基本数据的简单应用,对象的简单应用 数组的简单应用 局部使用vue框架步骤 1 引用 vue框架的核心文件和 涉及ES6语法的文件 注意:这里文件&am…

初识Linux · IP分片

目录 前言: IP分片 分片vs不分片 如何分片 分片举例 三个字段 前言: 前文IP协议上和IP协议下我们已经把IP协议的报头的大多数字段介绍了,唯独有三个字段现在还有介绍,即16位标识,8位协议,13位片偏移…

u3d 定义列表详细过程

层级结构 - Canvas - Scroll View - Viewport - Content (Vertical Layout Group) - Item1 (Prefab) - Item2 (Prefab) ... 详细设置步骤 1. 创建 Canvas 2. 添加 Scroll View 组件 3. 在 Scroll View 下创建 Content 子对象 4. 添加 …

产品方法论与 AI Agent 技术的深度融合:从决策智能到价值创造

一、引言:智能化时代的产品范式革命 在数字化转型的深水区,产品开发正经历着从 “功能定义” 到 “体验设计” 再到 “智能演化” 的范式跃迁。麦肯锡 2024 年报告指出,采用 AI 驱动产品方法论的企业,新品研发周期平均缩短 40%&a…

力扣.1471数组的k个最强值,力扣.1471数组的k个最强值力扣1576.替换所有的问号力扣1419.数青蛙​编辑力扣300.最长递增子序列

目录 力扣.1471数组的k个最强值 力扣1576.替换所有的问号 力扣1419.数青蛙​编辑 力扣300.最长递增子序列 力扣.1471数组的k个最强值 class Solution {public static int[] getStrongest(int[] arr,int k) {if(karr.length){return arr;}int []retnew int[k];int narr.lengt…

使用docker安装clickhouse集群

1、简介 clickhouse 作为大数据场景中,实现快速检索的常用列式存储数据库,采用物理机部署,会在数据量大的场景中,物理机器存储达到阈值需要扩容,会带来比较大的问题,因此,使用docker部署clickho…

package-lock.json能否直接删除?

package-lock.json能否直接删除? package-lock.json 生成工具:由 npm 自动生成。 触发条件:当运行 npm install 时,如果不存在 package-lock.json,npm 会创建它;如果已存在,npm 会根据它精确安…

如何在 Windows 命令提示符中创建多个文件夹和多个文件

如何在 Windows 命令提示符中创建多个文件夹和多个文件 虽然大多数用户习惯使用 Windows 图形界面来创建文件夹,但如果你需要一次性创建多个文件夹或文件,如同在类Unix系统中可以使用mkdir和touch命令一样,windows下也有创建目录和文件的对应…

leetcode - 滑动窗口问题集

目录 前言 题1 长度最小的子数组: 思考: 参考代码1: 参考代码2: 题2 无重复字符的最长子串: 思考: 参考代码1: 参考代码2: 题3 最大连续1的个数 III: 思考&am…

Ubuntu20.04下如何源码编译Carla,使用UE4源码开跑,踩坑集合

一、简介 作为一个从事算法研究的人员,无人驾驶仿真一直是比较重要的一部分,但是现在比较常见的算法验证都是在carla这个开源仿真平台上做的,所以我有二次开发carla的需求,今天就来讲讲编译CARLA。 网上的教材很多,但还是推荐大家看官网教程:Linux build - CARLA Simul…

Linux云计算训练营笔记day09(MySQL数据库)

Linux云计算训练营笔记day09(MySQL数据库) 目录 Linux云计算训练营笔记day09(MySQL数据库)外键约束数据的导入和导出数据的导出数据的导入 DQL 数据查询语言查指定字段查所有字段where 过滤条件and 和 orin 和 not inbetween...an…

对心理幸福感含义的探索 | 幸福就是一切吗?

注:机翻,未校。 Happiness Is Everything, or Is It? Explorations on the Meaning of Psychological Well-Being 幸福就是一切吗?对心理幸福感含义的探索 Journal of Personality and Social Psychology 1989, Vol. 57, No. 6,1069-1081 …

零基础学Java——第十一章:实战项目 - 微服务入门

第十一章:实战项目 - 微服务入门 随着互联网应用的复杂性不断增加,单体应用(Monolithic Application)在可扩展性、可维护性、技术栈灵活性等方面逐渐暴露出一些问题。微服务架构(Microservices Architecture&#xff…

git 本地提交后修改注释

dos命令行进入目录,idea可以点击Terminal 进入命令行 git commit --amend -m "修改内容"