Sets and Sorted Sets
[!NOTE]
This module explores the core principles of Sets and Sorted Sets, deriving solutions from first principles and hardware constraints to build world-class, production-ready expertise.
1. Sets: Unordered & Unique
Redis Sets store unique strings. They are perfect for filtering duplicates and performing set theory operations.
- Complexity: O(1) for Add/Remove/Check.
- Internals: Hashtable (or IntSet if small integers).
Use Case: Common Friends (Intersection)
User A follows [1, 2, 3]. User B follows [2, 3, 4]. Common: [2, 3].
jedis.sadd("user:A:follows", "1", "2", "3");
jedis.sadd("user:B:follows", "2", "3", "4");
// SINTER = Set Intersection
Set<String> common = jedis.sinter("user:A:follows", "user:B:follows");
// Returns ["2", "3"]
rdb.SAdd(ctx, "user:A:follows", "1", "2", "3")
rdb.SAdd(ctx, "user:B:follows", "2", "3", "4")
common, _ := rdb.SInter(ctx, "user:A:follows", "user:B:follows").Result()
// Returns ["2", "3"]
2. Sorted Sets (ZSets): The Crown Jewel
ZSets are unique strings ordered by a floating-point Score. This is Redis’s most powerful structure.
- Complexity: O(log N) for Add/Remove/Rank.
- Use Cases: Leaderboards, Priority Queues, Rate Limiting (Sliding Window).
Internals: The Skip List
How does Redis maintain order efficiently? It uses a Skip List.
- Linked List: O(N) search.
- Skip List: Adds layers of “express lanes” to skip over elements. Complexity becomes O(log N) on average.
3. Interactive: Skip List Visualizer
Search for 50. See how we skip the lower levels to find it faster.
4. Real-World Example: Gaming Leaderboard
Store millions of players and get the top 10 in milliseconds.
// 1. Update Score
jedis.zadd("leaderboard", 1500, "player_alice");
// 2. Get Top 3 (Reverse Range)
// 0 is first, 2 is third
List<String> top3 = jedis.zrevrange("leaderboard", 0, 2);
// 3. Get Rank of Alice
long rank = jedis.zrevrank("leaderboard", "player_alice");
// Returns 0 if first place
// 1. Update Score
rdb.ZAdd(ctx, "leaderboard", redis.Z{Score: 1500, Member: "player_alice"})
// 2. Get Top 3
top3, _ := rdb.ZRevRange(ctx, "leaderboard", 0, 2).Result()
// 3. Get Rank
rank, _ := rdb.ZRevRank(ctx, "leaderboard", "player_alice").Result()