数据结构
数据结构总览表
字符串(String)
-
简单动态字符串(SDS) :这是 Redis 对字符串的底层实现,与 C 语言传统字符串不同。SDS 结构体记录了字符串的长度、分配空间等信息,具有以下优势:
- 二进制安全:可以存储任意二进制数据,如图片、音频等,而不仅限于文本。
- 获取长度时间复杂度为 (O(1)):C 语言字符串获取长度需遍历,而 SDS 直接读取记录的长度信息。
- 避免缓冲区溢出:在修改字符串时,SDS 会先检查空间是否足够,不足时自动扩展。
2. 哈希(Hash)
- 压缩列表(ziplist) :当哈希对象保存的键值对数量较少,且键和值的长度都较短时使用。它是一种紧凑的内存数据结构,将多个键值对依次存储在连续的内存块中,节省内存,但查找效率相对较低。
- 哈希表(hashtable) :也叫字典,是 Redis 哈希类型的主要底层结构之一。当哈希对象中的键值对数量较多,或者键和值的长度较长时,Redis 会使用哈希表。它通过哈希函数将键映射到数组的某个位置,若发生哈希冲突,则使用链表将冲突的元素连接起来,查找、插入和删除操作的平均时间复杂度为 (O(1))。
3. 列表(List)
- 压缩列表(ziplist) :当列表元素较少且元素长度较短时采用,将元素紧凑存储在连续内存中,节省内存空间。
- 双向链表(linkedlist) :当列表元素数量较多或元素长度较长时使用。双向链表的每个节点包含指向前一个节点和后一个节点的指针,便于在列表两端进行快速的插入和删除操作,时间复杂度为 (O(1)),但随机访问效率较低。
- 快速列表(quicklist) :Redis 3.2 版本引入,结合了压缩列表和双向链表的优点。它将双向链表按段切分,每一段使用压缩列表存储数据,既保留了双向链表的快速插入和删除特性,又通过压缩列表节省了内存。
4. 集合(Set)
- 整数数组(intset) :当集合中的所有元素都是整数值,且元素数量较少时使用。整数集合是一个有序的、无重复元素的整数数组,会根据元素大小自动调整存储类型,以节省内存。
- 哈希表(hashtable) :当集合中的元素包含非整数值,或者元素数量较多时使用。哈希表通过哈希函数将元素映射到数组的某个位置,能快速判断元素是否存在于集合中,插入、删除和查找操作的平均时间复杂度为 (O(1))。
5. 有序集合(Sorted Set)
- 压缩列表(ziplist) :当有序集合的元素数量较少,且元素的成员和分值都较短时使用。在压缩列表中,元素的成员和分值依次存储,且按分值从小到大排序。
- 跳跃表(skiplist) 和 哈希表(hashtable) :当有序集合的元素数量较多,或者元素的成员和分值较长时,Redis 同时使用这两种结构。跳跃表是一种有序的数据结构,通过在每个节点中维护多个指向其他节点的指针,在查找元素时可跳过部分节点,提高查找效率;哈希表用于快速查找元素的分值,使获取元素分值的时间复杂度为 (O(1))。
使用场景
字符串(String)
使用场景
- 缓存:将数据库查询结果、页面片段等数据缓存为字符串,减少数据库访问压力,提高系统响应速度。例如,缓存热门文章的内容。
- 计数器:利用字符串的原子性自增、自减操作实现计数功能,如网站的访问量统计、文章的点赞数等。
- 分布式锁:通过设置一个特定的字符串键值对来实现分布式锁,保证在分布式环境下同一时间只有一个客户端可以执行某段代码。
常用命令
收起
plaintext
# 设置键值对
SET key value
# 获取键对应的值
GET key
# 原子性自增 1
INCR key
# 原子性自减 1
DECR key
# 原子性增加指定数值
INCRBY key increment
# 原子性减少指定数值
DECRBY key decrement
2. 哈希(Hash)
使用场景
- 对象存储:可以将一个对象的各个属性存储为哈希表的字段和值,方便对对象的属性进行单独操作。例如,存储用户信息,每个用户的 ID 作为键,用户的姓名、年龄、邮箱等属性作为字段和值。
- 存储配置信息:将系统的配置信息以哈希表的形式存储,便于修改和获取。
常用命令
收起
plaintext
# 设置哈希表中指定字段的值
HSET key field value
# 获取哈希表中指定字段的值
HGET key field
# 获取哈希表中所有的字段和值
HGETALL key
# 检查哈希表中是否存在指定字段
HEXISTS key field
# 删除哈希表中指定的字段
HDEL key field [field ...]
3. 列表(List)
使用场景
- 消息队列:利用列表的
LPUSH和RPOP或RPUSH和LPOP操作实现简单的消息队列,用于异步任务处理、系统间的消息传递等。 - 最新消息列表:可以将最新的消息依次添加到列表的头部,实现类似微博、朋友圈等的最新消息展示。
常用命令
收起
plaintext
# 将一个或多个值插入到列表的头部
LPUSH key value [value ...]
# 将一个或多个值插入到列表的尾部
RPUSH key value [value ...]
# 移除并返回列表的头部元素
LPOP key
# 移除并返回列表的尾部元素
RPOP key
# 获取列表指定范围内的元素
LRANGE key start stop
4. 集合(Set)
使用场景
- 去重:集合中的元素是唯一的,可以用于对数据进行去重处理。例如,统计网站的独立访客数。
- 交集、并集、差集运算:可以利用集合的这些运算来实现如共同好友、推荐系统等功能。例如,计算两个用户的共同好友。
- 随机选取元素:可以从集合中随机选取元素,用于抽奖、随机推荐等场景。
- 微博微信关注模型
常用命令
收起
plaintext
# 向集合中添加一个或多个元素
SADD key member [member ...]
# 移除集合中一个或多个元素
SREM key member [member ...]
# 获取集合中的所有元素
SMEMBERS key
# 检查元素是否存在于集合中
SISMEMBER key member
# 计算多个集合的交集
SINTER key [key ...]
# 计算多个集合的并集
SUNION key [key ...]
# 计算多个集合的差集
SDIFF key [key ...]
# 随机获取集合中的一个元素
SRANDMEMBER key
5. 有序集合(Sorted Set)
使用场景
- 排行榜:根据元素的分值进行排序,可以方便地实现各种排行榜功能,如游戏的玩家积分排行榜、文章的热度排行榜等。
- 时间序列数据:可以将时间作为分值,将事件或数据作为成员,实现按时间排序的存储和查询。
常用命令
收起
plaintext
# 向有序集合中添加一个或多个元素,并指定分值
ZADD key score member [score member ...]
# 获取有序集合中指定成员的分值
ZSCORE key member
# 获取有序集合中指定范围内的元素(按分值从小到大排序)
ZRANGE key start stop [WITHSCORES]
# 获取有序集合中指定范围内的元素(按分值从大到小排序)
ZREVRANGE key start stop [WITHSCORES]
# 获取有序集合中指定分值范围内的元素数量
ZCOUNT key min max
# 移除有序集合中指定的元素
ZREM key member [member ...]