Redis中的集合是如何实现排序的

128 阅读3分钟
  1. 无序集合(普通Set)
    • Redis中的普通集合(Set)是无序的。它主要基于哈希表(Hash Table)或者整数集合(IntSet)实现。
    • 以哈希表为例,元素存储在哈希表中时,其存储位置是通过哈希函数计算得到的,这个过程并没有考虑元素之间的顺序。哈希函数的目的是为了快速地定位元素,实现高效的插入、删除和查找操作,而不是按照某种特定的顺序来排列元素。例如,使用SADD命令向集合中添加元素,这些元素在集合中的实际存储位置是由哈希函数决定的,并不是按照添加的先后顺序或者其他规则排序。
  2. 有序集合(Sorted Set)
    • 数据结构基础:Redis的有序集合(Sorted Set)是一种可以对元素进行排序的数据结构。它在底层是通过跳跃表(Skip List)和哈希表(Hash Table)组合实现的。哈希表用于快速查找元素,跳跃表用于实现元素的有序排列。
    • 排序依据:有序集合中的每个元素都关联一个分数(score),元素会根据这个分数进行排序。分数可以是整数或者浮点数。例如,在一个存储用户成绩的有序集合中,用户的成绩可以作为分数,用户ID作为元素。当执行ZRANGE命令(按照分数从小到大排序返回元素)或者ZREVRANGE命令(按照分数从大到小排序返回元素)时,Redis会根据元素关联的分数来确定元素的顺序。
    • 跳跃表工作原理:跳跃表是一种分层的数据结构,它类似于多个链表叠加在一起。最底层的链表包含了有序集合中的所有元素。每个较高层的链表都是下层链表的一个子序列,元素间隔逐渐增大。这样在查找元素时,可以通过在高层链表中快速跳过一些元素,减少查找的步骤。例如,假设我们有一个有序集合,元素为[1, 3, 5, 7, 9],其对应的跳跃表可能有三层。最底层包含所有元素,第二层可能只包含[1, 5, 9],第三层只包含[1, 9]。当查找元素7时,可以先在高层链表中快速定位到大致范围,然后在底层链表中精确查找,从而提高排序和查找的效率。
    • 插入和更新元素对排序的影响:当向有序集合中插入一个新元素时,Redis会根据新元素的分数来确定它在跳跃表中的位置。如果更新了一个现有元素的分数,Redis会将该元素从原来的位置移除,然后根据新的分数重新插入到合适的位置,以保持整个有序集合的排序状态。