Redis数据类型——列表(链表与数组的差别对比)

本文深入探讨Redis列表数据结构,解析其作为双向链表的特点及优势,对比数组在内存使用和操作上的不同,并介绍典型应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

Redis的列表其实就是一个双向链表,他对于操作列表里面的数据就是0(1)的时间复杂度,到这里我们说一下链表和数组对于内存中的优劣势

其实在c或者c++中每一个变量的申明都会去内存申请空间,然而我们知道数组类型来说就是一段连续的,而对于链表来说他可以是不连续的,如果后面有别的变量占用了内存他就会寻找下一个空缺位置然后位置告诉指针就可以。数组内存存储因为是连续的他要么就是把后面的往后延要么就是重新申请一片足够容纳新数组的内存空间。

以上的结果我们可以看出来:数组必须是在内存中是有一段连续的内存,所以在存储空间有限的情况下数组是慎之又慎的去选择用,申请的多了其他的空间就会浪费,申请的少了就会遇到后期添加的时候对于内存的申请和占用造成不必要的时间浪费。所以对于链表和数组的优劣性一看就已经明白了。因为数组是连续的对于数据的查询是一步到位可以说是0(1)的时间复杂度,然而相对于链表来说就是0(n)的时间复杂度了,因为他所处的是一段不连续的内存空间,要由指针去一一查询。对于增删这种操作来说链表就体现出它的优势了,只要告诉指针删除或者添加键值,就会在内存中找出一点内存存进值在链表中记录键值就可以,时间复杂度为0(1),对于数组来说会重新审批内存这样,它的复杂度就是0(n)了

应用场景:像我前面写的那篇swoole 队列来做消息通知功能就可以用列表来做,最常用的就是博客文章或者是新闻这一类的存储id然后再首页显示的时候前100条或者多少条来取,这样的按块来取Redis列表提供了函数LRANGE key start stop  这样的来取

### Redis 数据类型及其底层数据结构详解 Redis 是一种高性能的键值数据库,支持多种数据类型。每种数据类型的实现都依赖于特定的数据结构来满足不同的应用场景和性能需求。 #### 字符串(String) 字符串是最基本的数据类型之一,在 Redis 中表示为 `redisObject` 结构体中的 `type` 属性设置为 `REDIS_STRING`[^2]。其底层实现主要基于 **SDS (Simple Dynamic String)**,即简单的动态字符串。相比 C 语言中原生的字符数组,SDS 提供了更高效的内存管理和操作能力[^3]。 ```c // SDS 示例定义 struct sdshdr { int len; // 当前长度 int free; // 可用空间大小 char buf[]; // 实际存储数据的缓冲区 }; ``` #### 列表ListRedis列表是一种双向链表,由多个节点组成,每个节点保存一个字符串对象。当列表元素较少时,为了节省内存开销,Redis 使用 **压缩列表(ziplist)** 或者从 Redis 7.0 开始使用的 **listpack** 来存储;而当列表较大时,则切换到标准的 **Linked List** 实现。 ```c typedef struct listNode { struct listNode *prev; struct listNode *next; void *value; } listNode; typedef struct list { listNode *head; listNode *tail; unsigned long len; void *(*dup)(void *ptr); void (*free)(void *ptr); int (*match)(void *ptr, void *key); } list; ``` #### 哈希(Hash) 哈希用于存储字段-值对的形式,类似于字典或者映射关系。如果字段数量较小,Redis 将采用 **zipmap**(已废弃)或 **ziplist/listpack** 进行紧凑存储;随着字段增多,会升级至 **哈希表(dict)** 形式以提高查询效率。 ```c // Dict 表头结构 typedef struct dictht { dictEntry **table; unsigned long size; unsigned long sizemask; unsigned long used; } dictht; typedef struct dict { dictht ht[2]; ... } dict; ``` #### 集合(Set) 集合是一个无序且不允许重复成员的容器。对于小型集合,Redis 使用 **intset** 存储整数值集;而对于通用情况则利用 **hashtable** 完成快速查找功能。 ```c // Intset 整型集合定义 typedef struct intset { uint32_t encoding; uint32_t length; int8_t contents[]; } intset; ``` #### 有序集合(Sorted Set) 有序集合除了具备普通集合特性外还能按照分值排序。它通过双层索引来达成目标——一方面依靠 **skip list** 维护顺序访问路径,另一方面借助 **hash table** 加速随机定位速度。 ```c // Zset 节点描述 typedef struct zskiplistNode { double score; robj *obj; struct zskiplistNode *backward; struct zskiplistLevel level[]; } zskiplistNode; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值