如何在Redis中存储复杂的JSON对象_对比String序列化与RedisJSON模块

P粉602998670

P粉602998670

2026-07-03

458人浏览

原创

应避免直接用set存json字符串,因其不支持字段级操作、易并发覆盖、无格式校验;推荐优先使用redisjson模块(需确认已启用),次选hash扁平化存储。

如何在redis中存储复杂的json对象_对比string序列化与redisjson模块

直接存复杂 JSON 对象,别无脑用 SET + JSON.stringify() —— 除非你确定永远只整条读写、不改字段、不查嵌套、不担心并发覆盖。真要操作嵌套结构或高频更新子字段,String 类型就是给自己埋雷。

SET 存整个 JSON 字符串的硬伤

看似最简单,实则限制最多:

  • GET 后必须全量反序列化才能取一个 address.city,CPU 和带宽白耗
  • 改一个字段得 GET → parse → mutate → stringify → SET,四步操作 + 两次网络往返,高并发下容易丢更新
  • Redis 不校验 JSON 格式,SET user:1001 '{"name":"Alice",}'(末尾多逗号)完全合法,直到业务层 JSON.parse() 才崩出 SyntaxError: Unexpected token
  • 空值处理混乱:nullundefined"null" 在序列化后语义全乱,前端解析时容易误判
  • 无法做路径查询,比如“找出所有 status == "active" 的用户”,只能遍历所有 key + 全量解析,O(n) 级别扫库

启用 RedisJSON 模块前必须确认的三件事

它不是 Redis 内置功能,很多环境默认没开:

php版微信js-sdk支付接口类
php版微信js-sdk支付接口类

php版微信js-sdk支付接口类

下载
  • 连上 Redis 后执行 MODULE LIST,检查输出里有没有 name:RedisJSONname:rejson;没有就别往下试
  • Docker 用户优先用官方镜像 redis/json,不是 redis:alpine;云数据库(如阿里云、腾讯云 Redis)需单独确认是否开通 RedisJSON 插件,多数默认关闭
  • 模块版本建议 ≥ v2.4,老版本(如 v1.x)对 $.. 通配路径支持不全,JSON.GET user:1001 $..city 可能返回空

JSON.SETJSON.GET 的参数陷阱

命令行为和原生 SET/GET 完全不同,错一个字符就失败:

  • JSON.SET user:1001 $ '{"name":"Alice","address":{"city":"Beijing"}}':第二个参数必须是 JSONPath 表达式,$ 是根节点,不能省略
  • JSON.GET user:1001 $.name 返回 "Alice"(带双引号),不是 Alice;若要取原始字符串值,得在客户端再 JSON.parse() 一次
  • 更新子字段时,值必须是合法 JSON 字符串:JSON.SET user:1001 $.address.city '"Shanghai"' —— 注意外层单引号包裹、内层双引号保留;写成 "Shanghai"Shanghai 都会报 ERR invalid JSON
  • JSON.DEL user:1001 $.tags 删除字段后,该路径彻底消失;而 HDEL user:1001 tags 在 HASH 中只是删 field,语义更轻量

嵌套深、字段多但环境不支持 RedisJSON?用 HASH 扁平化代替

String 强在原子性和内存效率,比 RedisJSON 强在零依赖:

  • {"user":{"profile":{"name":"Alice","age":30},"settings":{"theme":"dark"}} 扁平成 HSET user:1001 profile:name "Alice" profile:age "30" settings:theme "dark"
  • 字段名含点号不影响 HSET,但部分旧客户端(如 Jedis 2.x)解析 HGETALL 结果时可能出错,统一用下划线更稳:profile_name
  • HGET user:1001 profile_age 返回字符串 "30",业务层必须自己 parseInt;数字精度丢失风险(如 30.00000000000001 被截断)得提前防御
  • 不支持真正嵌套,但对大多数业务对象(用户资料、商品属性、配置项)已够用;HLEN user:1001 查字段数比 STRLEN 查 JSON 长度快得多,适合监控元数据

真正难的是权衡点:如果字段更新频率低、嵌套不超过两层、团队不熟悉 JSONPath,HASH 往往比强行上 RedisJSON 更可靠;而一旦需要 $..items[?(@.price > 100)] 这类动态查询,又没法说服运维加模块——那只能在应用层做缓存预计算,别把压力全推给 Redis。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

2933

3

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

2023.06.20

1856

8

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.28

890

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1154

5

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

2023.08.17

7909

11

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

638

4

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

1233

5

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.14

1058

5

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

2023.09.21

1975

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 9万人学习