Core Data Structures II: Sets & Sorted Sets
๐ฏ Core Data Structures II: Sets & Sorted Sets
Sets: Unique, Unordered Collections
A Redis set holds unique members with no defined order โ adding the same value twice has no effect, and duplicates are automatically rejected.
Note the return value: 2, not 3 โ the second "redis" was silently ignored as a duplicate, exactly what a set is for.
SINTER computes the intersection of multiple sets โ useful for "which members appear in both of these collections":
Sorted Sets: Ordered by Score
A sorted set combines a set's uniqueness with an explicit numeric score per member โ Redis maintains the members in score order automatically, regardless of insertion order.
ZRANGE returns members in ascending score order regardless of the order they were added โ alice (added first) still comes before bob because 42 < 91, not because of insertion order.
The Leaderboard Pattern
A sorted set is the textbook fit for a game leaderboard: score as the ranking value, ZREVRANGE for highest-first, ZSCORE to look up one player, ZRANK for their position.
The Sliding-Window Counter Pattern
Sorted sets also power a classic real-world Redis pattern: rate limiting via a sliding window. Each request is added with the current timestamp as its score; old entries outside the window are pruned; the remaining count is the request count within that window โ the exact mechanism behind Chapter 10's capstone.
Set vs. Sorted Set
Set
Unique members, no order at all โ good for membership tests and intersections (tags, "has this user done X").
Sorted Set
Unique members, ordered by an explicit score โ good for rankings, leaderboards, and time-windowed data.
| Command | Structure | Purpose |
|---|---|---|
SADD / SMEMBERS | Set | Add members; list all members |
SINTER | Set | Intersection of multiple sets |
ZADD | Sorted Set | Add a member with a numeric score |
ZRANGE / ZREVRANGE | Sorted Set | Read members in ascending / descending score order |
ZSCORE / ZRANK | Sorted Set | Look up one member's score / rank position |
ZREMRANGEBYSCORE | Sorted Set | Remove members whose score falls in a range (pruning old entries) |
ZCARD | Sorted Set | Count members in a sorted set |
๐ป Coding Challenges
Challenge 1: Find Shared Tags
Two posts have tags stored as sets: post:1:tags = {redis, databases, nosql} and post:2:tags = {redis, sql, databases}. Write the command to find tags shared by both posts.
Goal: Practice SINTER for a realistic "what do these two collections have in common" scenario.
Challenge 2: Build a Mini Leaderboard
Add three players to a sorted set called game:leaderboard with scores 300, 750, and 500. Write the command to retrieve them highest-score-first, with scores shown.
Goal: Practice ZADD and ZREVRANGE WITHSCORES together for the standard leaderboard read.
Challenge 3: Explain the Sliding-Window Pattern
Explain, in your own words, why a sorted set with timestamps as scores is a good fit for rate limiting, and what role ZREMRANGEBYSCORE plays in keeping the count accurate over time.
Goal: Practice explaining the mechanics behind this chapter's rate-limiting pattern, not just running the commands.
When two members in a sorted set have the exact same score, Redis doesn't leave their relative order undefined โ it breaks the tie by comparing the members themselves in lexicographic (dictionary) order. This is easy to overlook until it produces a surprising leaderboard: two players tied at the same score will always appear in the same relative order (by name), not in insertion order or randomly, every time the sorted set is read. If tie-breaking by name isn't the desired behavior, the score itself needs to encode enough information to break ties meaningfully (e.g. combining a primary score with a secondary tiebreaker value).
๐ฏ What's Next
The next chapter is Expiration & Caching Patterns โ TTL/EXPIRE, the cache-aside pattern, and cache stampede prevention, deepening node3-5's brief mention of Redis caching.