Redis从入门到精通之底层数据结构字典/哈希表详解

简介: Redis中的字典(Dictionary)是一种高效的数据结构,用于存储键值对,常用于实现哈希表(Hash Table)。在本文中,我们将深入了解Redis中的字典/哈希表,包括字典的结构和操作等。字典/哈希表适合存储大量的键值对,并需要快速地查找键对应的值的场景。在实际应用中,需要根据具体的业务场景选择合适的底层数据结构。例如,如果需要按照键的顺序进行访问,可以使用有序集合(Sorted Set)等其他数据结构。

Redis中的字典(Dictionary)是一种高效的数据结构,用于存储键值对,常用于实现哈希表(Hash Table)。在本文中,我们将深入了解Redis中的字典/哈希表,包括字典的结构和操作等。
image.png
图1 哈希表(Hash Table)

1. 字典的结构

Redis中的字典(Dictionary)是由多个哈希表(Hash Table 如图1)组成的,每个哈希表都包含了多个哈希桶(Hash Bucket)。哈希表的结构如下图所示:

+---------+---------+---------+-------+
|  bucket |  bucket |  bucket |  ...  |
+---------+---------+---------+-------+
|  ...    |  ...    |  ...    |  ...  |
+---------+---------+---------+-------+

其中,bucket是哈希桶,包含了多个键值对。每个键值对包含了一个键和一个值,键和值可以是任意数据类型,但键必须是唯一的。哈希表的大小是固定的,当哈希桶中的键值对数量超过一定阈值时,需要对哈希表进行扩容操作,以保持哈希表的高效性。

2. 源码层字典的操作

  • 字典的创建
dict *d = dictCreate(&myDictType, NULL);

其中,myDictType是一个字典类型结构体,包含了键和值的比较函数,以及哈希函数等信息。NULL表示不定义私有数据。

  • 字典的添加
int dictAdd(dict *d, void *key, void *val);

其中,key是要添加的键,val是要添加的值。

  • 字典的删除
int dictDelete(dict *d, const void *key);

其中,key是要删除的键。

  • 字典的查找
void *dictFind(dict *d, const void *key);

其中,key是要查找的键,返回值是对应键的值。

  • 字典的遍历
dictIterator *di = dictGetIterator(d);
dictEntry *de;
while ((de = dictNext(di)) != NULL) {
   
    printf("%s: %s\n", (char *)de->key, (char *)de->val);
}
dictReleaseIterator(di);

其中,dictIterator是字典的迭代器,dictEntry是字典中的键值对。dictGetIterator函数返回一个字典的迭代器,dictNext函数用于获取字典中的下一个键值对,dictReleaseIterator函数用于释放迭代器。

  • 字典的大小
unsigned long dictSize(const dict *d);

还有其他的操作可以参考Redis源代码中的dict.h和dict.c文件。

3. 字典/哈希表的优缺点

3.1 优点

3.1.1. 快速的查找时间

提供了常数时间复杂度O(1)的键值对查找,这意味着查找与字典大小无关,即使对于非常大的字典,查找时间也非常快。

3.1.2. 动态调整大小

字典/哈希表支持动态调整大小以适应数据的增长或减少。当某个哈希桶中的键值对数量超过一定阈值时,Redis会自动调整哈希桶的大小,以确保字典的高效性。这意味着Redis可以处理大量的数据而不会导致显著的性能损失。

3.1.3. 灵活的数据类型

可以存储任意数据类型的键和值,这使它非常灵活。这意味着它可以用于各种应用场景,从简单的键值存储到更复杂的数据结构。

3.2 缺点

  • 哈希表的空间利用率可能较低,当哈希桶中的键值对数量较少时,会浪费一定的空间。
  • 哈希表的扩容和缩容可能会造成性能损失,因为需要重新计算哈希值、重新分配内存等操作。
  • 哈希表中的键的顺序是无序的,不适合存储需要按照键的顺序进行访问的数据。

    4.总结

    字典/哈希表适合存储大量的键值对,并需要快速地查找键对应的值的场景。在实际应用中,需要根据具体的业务场景选择合适的底层数据结构。例如,如果需要按照键的顺序进行访问,可以使用有序集合(Sorted Set)等其他数据结构。
目录
相关文章
|
存储 缓存 NoSQL
Redis 服务器全方位介绍:从入门到核心原理
Redis是一款高性能内存键值数据库,支持字符串、哈希、列表等多种数据结构,广泛用于缓存、会话存储、排行榜及消息队列。其单线程事件循环架构保障高并发与低延迟,结合RDB和AOF持久化机制兼顾性能与数据安全。通过主从复制、哨兵及集群模式实现高可用与横向扩展,适用于现代应用的多样化场景。合理配置与优化可显著提升系统性能与稳定性。
727 0
|
8月前
|
存储 缓存 NoSQL
【📕分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch
本文解析 Redisson 如何通过 Redis 实现分布式信号量(RSemaphore)与倒数闩(RCountDownLatch),利用 Lua 脚本与原子操作保障分布式环境下的同步控制,帮助开发者更好地理解其原理与应用。
491 6
|
7月前
|
消息中间件 缓存 NoSQL
Redis各类数据结构详细介绍及其在Go语言Gin框架下实践应用
这只是利用Go语言和Gin框架与Redis交互最基础部分展示;根据具体业务需求可能需要更复杂查询、事务处理或订阅发布功能实现更多高级特性应用场景。
413 86
|
9月前
|
存储 缓存 NoSQL
Redis核心数据结构与分布式锁实现详解
Redis 是高性能键值数据库,支持多种数据结构,如字符串、列表、集合、哈希、有序集合等,广泛用于缓存、消息队列和实时数据处理。本文详解其核心数据结构及分布式锁实现,帮助开发者提升系统性能与并发控制能力。
|
7月前
|
存储 消息中间件 NoSQL
Redis数据结构:别小看这5把“瑞士军刀”,用好了性能飙升!
Redis提供5种基础数据结构及多种高级结构,如String、Hash、List、Set、ZSet,底层通过SDS、跳表等实现高效操作。灵活运用可解决缓存、计数、消息队列、排行榜等问题,结合Bitmap、HyperLogLog、GEO更可应对签到、UV统计、地理位置等场景,是高性能应用的核心利器。
|
7月前
|
存储 缓存 NoSQL
Redis基础命令与数据结构概览
Redis是一个功能强大的键值存储系统,提供了丰富的数据结构以及相应的操作命令来满足现代应用程序对于高速读写和灵活数据处理的需求。通过掌握这些基础命令,开发者能够高效地对Redis进行操作,实现数据存储和管理的高性能方案。
214 12
|
7月前
|
存储 消息中间件 NoSQL
【Redis】常用数据结构之List篇:从常用命令到典型使用场景
本文将系统探讨 Redis List 的核心特性、完整命令体系、底层存储实现以及典型实践场景,为读者构建从理论到应用的完整认知框架,助力开发者在实际业务中高效运用这一数据结构解决问题。
|
7月前
|
存储 缓存 NoSQL
【Redis】 常用数据结构之String篇:从SET/GET到INCR的超全教程
无论是需要快速缓存用户信息,还是实现高并发场景下的精准计数,深入理解String的特性与最佳实践,都是提升Redis使用效率的关键。接下来,让我们从基础命令开始,逐步揭开String数据结构的神秘面纱。
|
11月前
|
存储 NoSQL 算法
Redis设计与实现——数据结构与对象
Redis 是一个高性能的键值存储系统,其数据结构设计精妙且高效。主要包括以下几种核心数据结构:SDS、链表、字典、跳跃表、整数集合、压缩列表。此外,Redis 对象通过类型和编码方式动态转换,优化内存使用,并支持引用计数、共享对象和淘汰策略(如 LRU/LFU)。这些特性共同确保 Redis 在性能与灵活性之间的平衡。
438 12

热门文章

最新文章