Redis 中的 ZSET(Sorted Set)是一种数据结构,它类似于 SET,但是每个元素都关联一个分数(score),这些分数用于对集合中的成员进行排序。ZSET 支持按分数范围和成员排名来获取或删除成员。
实现方式
在 Redis 中,ZSET 的实现是通过结合两种不同的底层数据结构来完成的:跳跃表(Skip List)和哈希表(Hash Table)。这种组合确保了操作的高效性,同时保持了数据的有序性。
-
跳跃表(Skip List):
- 跳跃表是一种概率性的数据结构,它允许快速搜索、插入和删除操作。
- 在 ZSET 中,跳跃表用来维护成员按照分数排序的顺序。跳跃表中的每个节点包含成员及其对应的分数。
- 由于跳跃表的性质,查找、插入和删除的时间复杂度平均为 O(log N)。
-
哈希表(Hash Table):
- 哈希表提供了一种从成员到其在跳跃表中位置的快速映射。
- 这使得可以通过成员名直接访问跳跃表中的节点,而不需要遍历整个跳跃表。
- 哈希表保证了成员到分数的映射,以及成员到跳跃表节点的引用,从而实现了高效的随机访问。
操作效率
- 添加/更新成员: 平均时间复杂度为 O(log N),因为需要在跳跃表中找到正确的位置并可能调整哈希表。
- 移除成员: 平均时间复杂度同样为 O(log N),因为需要在跳跃表中定位成员,并从哈希表中移除该成员。
- 按分数范围查询成员: 可以利用跳跃表的有序性,在 O(log N + M) 时间内完成,其中 M 是返回的结果数量。
- 按排名范围查询成员: 类似地,可以在 O(log N + M) 时间内完成,因为跳跃表支持高效的排名访问。
- 成员排名查询: O(log N),因为在跳跃表中查找成员的位置是高效的。
内存使用
- 使用跳跃表和哈希表的组合可能会比单纯使用一种数据结构占用更多的内存空间。
- 但是,这样的设计提供了良好的性能平衡,尤其是在大规模数据集上。
总之,Redis 通过将跳跃表和哈希表结合起来实现了 ZSET,这种方式既保证了数据的有序性,又提供了高效的成员访问和操作能力。