news 2026/2/10 12:24:24

Redis的数据类型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis的数据类型

Redis 的核心设计思路是:为不同的基本类型提供 “多态” 的底层实现—— 会根据数据量、数据类型的不同,自动切换更高效的底层结构(优先用内存紧凑的结构,数据量大了再切换到性能更优的结构)。


1. 字符串(String):Redis 最基础的类型

用途

存字符串(如 "hello")、数字(如 123)、二进制数据(如图片、序列化对象),是 Redis 最常用的类型。

底层实现:SDS(简单动态字符串)

Redis 没有直接用 C 语言的字符串(char*),而是自己造了个叫SDS的结构,因为 C 字符串有 3 个致命缺点:

  • 获取长度要从头遍历(O (n));
  • 不能存空字符(\0),无法兼容二进制数据;
  • 修改时容易内存溢出。
SDS 的结构(通俗版)
+--------+--------+-----------+ | len | free | buf[] | | 已用长度 | 空闲长度 | 字符数组 | +--------+--------+-----------+

比如存 "redis",SDS 的结构是:

  • len=5("redis" 占 5 个字节);
  • free=0(暂时没空闲);
  • buf=['r','e','d','i','s','\0'](最后加 \0 是为了兼容 C 函数)。
额外优化

如果 String 存的是整数(且在 long 型范围内),Redis 不会真的用 SDS 存,而是直接把它当作整数存储(比如存 100,底层就是数字 100,不是字符串 "100"),节省内存且方便计算(比如 INCR 命令)。


2. 哈希(Hash):键值对的 “嵌套”

用途

存结构化数据,比如用户信息(user:1 → {name: 张三,age:20, city: 北京})。

底层实现:二选一(自动切换)

底层结构适用场景特点
ziplist(压缩列表)元素少(默认 < 512 个)+ 键 / 值长度短(默认 < 64 字节)连续内存块,紧凑省内存,修改稍慢
hashtable(字典)元素多 / 键值长哈希表结构,增删改查 O (1),内存稍多
通俗解释
  • ziplist:把所有键值对 “打包” 在一块连续的内存里,比如存 {name: 张三,age:20},内存里是 “name→张三→age→20” 连在一起,没有内存碎片,特别省空间。但如果要插入 / 删除中间的元素,需要重新分配整块内存,数据多了就慢。
  • hashtable:Redis 的字典结构,核心是 “数组 + 链表”(解决哈希冲突)。比如数组下标 0 存 “name”,下标 1 存 “age”;如果两个键哈希后落到同一个下标,就用链表串起来。另外,Redis 的哈希表会 “渐进式 rehash”(通俗说就是 “慢慢搬家”):当数据量变化需要扩容 / 缩容时,不会一次性把所有数据移到新表,而是分多次搬,避免 Redis 卡死。

3. 列表(List):有序的字符串队列

用途

两端操作的有序列表,比如消息队列、最新评论列表。

底层实现:二选一(Redis 3.2 后核心是 quicklist)

底层结构适用场景特点
ziplist(压缩列表)元素少 + 长度短紧凑省内存
quicklist(快速列表)元素多 / 长度长兼顾内存和性能(Redis 3.2 后默认)
通俗解释
  • 早期 Redis 用的是 linkedlist(双向链表),但链表的问题是 “内存碎片多”(每个节点都要存指针);而 ziplist 的问题是 “修改慢”。
  • quicklist:相当于 “把多个 ziplist 用双向链表串起来”—— 既解决了链表的内存碎片问题,又解决了单个 ziplist 修改慢的问题。比如一个 List 有 1000 个元素,Redis 会把它拆成 10 个 ziplist(每个 100 个元素),用链表连接这 10 个 ziplist,增删元素时只动其中一个 ziplist,效率高还省内存。

4. 集合(Set):无序、唯一的字符串集合

用途

去重、随机取值、交集 / 并集 / 差集(比如抽奖、好友共同关注)。

底层实现:二选一(自动切换)

底层结构适用场景特点
intset(整数集合)所有元素都是整数 + 个数少(默认 < 512 个)紧凑的整数数组,查询快(二分查找)
hashtable(字典)有非整数元素 / 元素个数多利用哈希表的唯一性,增删查 O (1)
通俗解释
  • intset:比如存 {1,3,5},底层是一个升序排列的整数数组 [1,3,5],查询时用二分查找(O (logn)),特别省内存。如果往里面加一个字符串(比如 "abc"),或者元素超过 512 个,就会自动转成 hashtable。
  • hashtable:存的时候 “键是集合元素,值是 NULL”(比如键 1→NULL,键 3→NULL),利用哈希表 “键唯一” 的特性保证 Set 的唯一性,增删查都是 O (1)。

5. 有序集合(ZSet):带分数的有序集合

用途

排行榜、带权重的队列(比如用户积分排名、热门商品排序)。

底层实现:二选一(自动切换)

底层结构适用场景特点
ziplist(压缩列表)元素少(默认 < 128 个)+ 元素长度短(默认 < 64 字节)紧凑省内存,按分数升序排列
skiplist+hashtable元素多 / 长度长兼顾排序和快速查询
通俗解释
  • ziplist:元素按分数升序排列,每个元素先存 “成员” 再存 “分数”(比如 “张三→95,李四→88”),紧凑存储,适合小数据量的 ZSet。
  • skiplist+hashtable(核心组合):
    • skiplist(跳表):可以理解成 “多层楼梯”—— 底层是完整的有序链表,上层是少量 “捷径节点”。比如查分数 95 的元素,先从最高层找,快速定位到底层的大致位置,再遍历,平均复杂度 O (logn),支持快速的范围查询(比如查分数 80-100 的元素)和排序。
    • hashtable:映射 “成员→分数”,比如查 “张三” 的分数,直接通过哈希表 O (1) 拿到,不用遍历跳表。两者结合,既保证了按分数排序的效率,又保证了查询单个元素分数的效率。

总结

  1. Redis 的基本类型都采用 “按需切换” 的底层实现:小数据量用紧凑结构(ziplist/intset)省内存,大数据量用高性能结构(hashtable/quicklist/skiplist)保速度
  2. 核心优化思路:平衡 “内存占用” 和 “操作性能”,避免单一结构的缺点(比如链表省性能但费内存,压缩列表省内存但改得慢)。
  3. 关键底层结构:SDS(String)、ziplist(小数据通用)、quicklist(List)、intset(Set 整数场景)、hashtable(Hash/Set/ZSet 通用)、skiplist(ZSet 核心)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 16:37:43

CANN模型调试:从算子级追踪到全链路性能瓶颈定位的智能诊断实战

CANN组织链接&#xff1a;https://atomgit.com/cann ops-nn仓库链接&#xff1a;https://atomgit.com/cann/ops-nn 当训练损失异常震荡却找不到梯度爆炸源头&#xff0c;当推理延迟突增却无法定位硬件瓶颈&#xff0c;当分布式训练通信开销飙升却查不出拓扑瓶颈——模型调试已成…

作者头像 李华
网站建设 2026/2/7 16:30:28

GDPR下的测试日志管理:构建合规高效的自动化防护体系

在持续交付管道中&#xff0c;测试日志如同数字世界的“ forensic 痕迹”&#xff0c;既承载着缺陷定位的关键线索&#xff0c;又潜藏着用户隐私泄露的高危风险。当欧盟用户数据流过测试环境时&#xff0c;GDPR第32条“处理安全性”要求如同悬顶之剑——测试团队必须证明&#…

作者头像 李华
网站建设 2026/2/7 16:27:37

2026年ChatGPT写的论文怎么去AIGC痕迹?3招轻松搞定

2026年ChatGPT写的论文怎么去AIGC痕迹&#xff1f;3招轻松搞定 ChatGPT是用得最多的AI写作工具&#xff0c;但也是AI痕迹最重的。 我室友用GPT-4写了一篇论文&#xff0c;一测AI率82%。比国产AI工具生成的内容还高。 为什么&#xff1f;因为各大检测平台的训练数据里&#x…

作者头像 李华
网站建设 2026/2/7 16:25:22

# [大模型实战 05] 大模型实战的杀手锏: 模型微调

[大模型实战 05] 大模型实战的杀手锏&#xff1a; 模型微调核心摘要 (TL;DR) 实操验证&#xff1a;通过 Kaggle 代码亲自运行对比&#xff0c;揭示 Base 模型&#xff08;“续写怪”&#xff09;与 Instruct 模型&#xff08;“对话助手”&#xff09;的本质差异。原理揭秘&…

作者头像 李华