Redis怎么搞对象存储,直接把对象往里头塞试试看
- 问答
- 2025-12-30 17:43:31
- 3
有人在网上问,Redis能不能当对象存储用,就是直接把整个对象,比如一个用户信息、一个商品详情,这种复杂的数据块,直接塞到Redis里面去,答案是,能,而且很多人就是这么干的,但这活儿不能蛮干,直接“试试看”可能会掉坑里,这就像你有一个大箱子,你确实可以把东西胡乱塞进去,但想找的时候可能就麻烦了,下面就直接说说怎么搞,以及要注意什么。
最直接、最傻白甜的办法,就是把你的对象转换成JSON字符串,然后把这个字符串当成一个字符串(String)类型的值,存到Redis里,比如你有一个用户对象,有ID、名字、年龄,你用你熟悉的编程语言(比如Python的json.dumps(),Java的Jackson库)把这个对象变成一串JSON文本,然后用Redis的SET命令,以一个键(user:123)为名字,把这串文本存进去,取的时候用GET命令拿到字符串,再解析回对象,这种方法简单粗暴,上手快,对于不那么复杂的场景,或者对象不大、不常变动的情况,凑合用用没问题,但它的毛病也很明显:第一,你每次想改对象里的一个字段,比如只更新年龄,你也得把整个JSON字符串读出来,在程序里解析成对象,改好年龄,再序列化成字符串,最后整个写回去,这效率很低,尤其是对象很大时,第二,Redis本身帮不上什么忙,它只知道这是个字符串,没法帮你根据对象内部的字段进行查询或者操作。
为了解决这个“动一发牵全身”的问题,Redis提供了一个更合适的工具:哈希(Hash),哈希这个结构,本身就像一个小型的键值对集合,你可以把你的对象想象成一个字典,每个字段名和字段值就是一对键值,比如还是那个用户对象,你可以用HSET命令,直接操作Redis里的这个哈希结构:HSET user:123 name "张三" age 30 email "zhangsan@example.com",这样一来,这个用户对象的所有字段就都存到键为 user:123 的哈希里面了,好处是什么呢?就是你更新年龄的时候,直接用HEST user:123 age 31就行了,Redis只会更新这一个字段,完全不用动名字和邮箱,读取也一样,可以用HGET读单个字段,或者用HGETALL把整个对象的所有字段一次性取回来,这种方式更符合我们操作对象的直觉,效率也高得多,对于大多数需要把对象当做一个整体来存取,又可能需要单独更新其中部分字段的场景,用哈希(Hash)类型是比用JSON字符串更推荐的做法。
上面这两种方法,无论是存字符串还是存哈希,都只解决了“存”的问题,没解决“查”的问题,比如你想找出所有年龄大于25岁的用户,用上面两种方法,Redis都无能为力,因为Redis的键本身是简单的字符串,它不会去解析你值里面的内容(无论是JSON还是哈希字段)来帮你做查询,你只能通过你知道的键,user:123,去直接获取那个用户的数据,要完成这种搜索,你得自己维护一套“索引”,比如再用一个集合(Set)或有序集合(Sorted Set),把符合某个条件的用户ID放进去,这就会变得很麻烦。
正因为有这个痛点,Redis官方后来推出了一个功能叫RedisJSON(来源:Redis官方文档),这是个扩展模块,你需要单独加载它,有了它,Redis就真的能“理解”JSON了,你可以直接把一个JSON对象塞给Redis,它内部会以一种优化的二进制格式存储,而不是单纯的字符串,更厉害的是,它提供了一系列命令,让你可以像在代码里操作JSON一样,在Redis内部进行精准的查询和修改,你可以直接查询“所有住在北京的用户”,或者“把某个用户的年龄字段增加1岁”,这些操作都可以在Redis服务器端完成,不需要把数据拉到客户端处理,这对于复杂对象和复杂查询的场景是革命性的,但缺点就是,你需要确保你的Redis服务器安装了这个模块,并且你的客户端库也要支持这些特殊的命令。
还有一个叫RediSearch的模块(来源:Redis官方文档),它更进了一步,专门提供强大的全文搜索和二级索引功能,可以和RedisJSON配合使用,实现非常灵活的查询。
回到“直接把对象往里头塞试试看”这个问题,结论是:
- 可以塞,但别乱塞。
- 如果对象简单,偶尔整体存取,用JSON字符串存成String类型,省事。
- 如果对象需要频繁更新部分字段,用哈希(Hash)类型是标准做法。
- 如果对象复杂,并且需要基于对象内部的字段进行各种灵活查询,强烈建议使用RedisJSON模块,甚至搭配RediSearch。
- 千万别忘了,无论用哪种方式,都要给每个对象设计一个清晰、唯一的键,
user:123,product:sku_abc这种形式,这是良好实践。
最后提一嘴,虽然Redis很快,但它毕竟是把所有数据放在内存里的,如果你要存的对象特别大(比如好几兆),或者数量极其庞大,你得仔细考虑你的内存够不够用,Redis也支持设置过期时间(TTL),对于缓存场景非常有用,用SETEX命令或者在存入后使用EXPIRE命令都可以,工具是好的,但得用对地方、用对方法才行。

本文由雪和泽于2025-12-30发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/71401.html
