news 2026/4/23 20:08:45

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/4/23 12:12:16

2026年去AIGC痕迹不伤原文:保留论文核心观点的技巧

2026年去AIGC痕迹不伤原文&#xff1a;保留论文核心观点的技巧 去AIGC痕迹最怕什么&#xff1f;改完之后论文意思变了。 之前用过一个免费工具&#xff0c;AI率是降下来了&#xff0c;但一看内容&#xff0c;好几个专业术语都换错了&#xff0c;论证逻辑也变得奇怪。还得自己…

作者头像 李华
网站建设 2026/4/23 12:15:57

【嵌入式就业5】硬件体系与RTOS核心机制:从ARM架构到实时调度

【嵌入式就业5】硬件体系与RTOS核心机制:从ARM架构到实时调度 作者:石去皿 专题说明:本系列聚焦嵌入式岗位求职实战。本文为第四篇,深度剖析ARM体系架构、中断机制、RTOS调度等硬件级核心知识,结合STM32/RK3588平台工程实践,助你攻克大厂硬件相关面试难点。 一、前言:硬…

作者头像 李华
网站建设 2026/4/23 13:44:20

2026年公文报告去AIGC痕迹:工作材料这样处理

2026年公文报告去AIGC痕迹&#xff1a;工作材料这样处理 用AI写工作报告、总结汇报&#xff0c;效率是高了&#xff0c;但被领导看出来就尴尬了。 同事小王用ChatGPT写了一份年终总结&#xff0c;领导一看就说"这写的怎么像机器写的"。虽然没说什么&#xff0c;但印…

作者头像 李华
网站建设 2026/4/23 8:35:20

【Linux命令大全】010.设备管理之dumpkeys命令(实操篇)

【Linux命令大全】010.设备管理之dumpkeys命令&#xff08;实操篇&#xff09; ✨ 本文为Linux设备管理命令的全面汇总与深度优化&#xff0c;结合图标、结构化排版与实用技巧&#xff0c;专为高级用户和系统管理员打造。 (关注不迷路哈&#xff01;&#xff01;&#xff01;) …

作者头像 李华