Redis Sets

Sets are unordered collections of unique strings. They provide O(1) membership testing and support powerful set operations like union, intersection, and difference.

Key Characteristics

• Unique members only (automatic deduplication) • O(1) add, remove, and membership test • Set operations: union, intersection, difference • Random member selection supported

Basic Operations

# Add members
SADD tags:post:1 "redis" "database" "nosql"
SADD tags:post:1 "redis"                # Returns 0 (already exists)

# Check membership
SISMEMBER tags:post:1 "redis"           # → 1 (true)
SISMEMBER tags:post:1 "mysql"           # → 0 (false)
SMISMEMBER tags:post:1 "redis" "mysql"  # Check multiple → [1, 0]

# Get all members
SMEMBERS tags:post:1

# Count members
SCARD tags:post:1                       # → 3

Remove Members

SREM tags:post:1 "nosql"                # Remove one member
SREM tags:post:1 "tag1" "tag2" "tag3"   # Remove multiple

# Pop random member(s)
SPOP tags:post:1                        # Remove and return 1 random
SPOP tags:post:1 3                      # Remove and return 3 random

Set Operations

Powerful operations for combining and comparing sets.

SADD tags:post:1 "redis" "database" "nosql"
SADD tags:post:2 "redis" "caching" "performance"

# Intersection (common elements)
SINTER tags:post:1 tags:post:2          # → ["redis"]

# Union (all unique elements)
SUNION tags:post:1 tags:post:2          # → all unique tags

# Difference (in first but not in second)
SDIFF tags:post:1 tags:post:2           # → ["database", "nosql"]
SDIFF tags:post:2 tags:post:1           # → ["caching", "performance"]

Store Set Operation Results

# Store intersection in new key
SINTERSTORE common:tags tags:post:1 tags:post:2

# Store union in new key
SUNIONSTORE all:tags tags:post:1 tags:post:2

# Store difference in new key
SDIFFSTORE unique:post1 tags:post:1 tags:post:2

Random Selection

# Get random member(s) without removing
SRANDMEMBER tags:post:1                 # 1 random member
SRANDMEMBER tags:post:1 3               # 3 random members
SRANDMEMBER tags:post:1 -3              # 3 random (may repeat)

# Pop random member(s) (removes them)
SPOP tags:post:1                        # Pop 1
SPOP tags:post:1 3                      # Pop 3

Move Between Sets

# Atomically move member between sets
SMOVE source_set dest_set "member"

# Example: Move user from pending to approved
SMOVE users:pending users:approved "user:123"

Scanning Large Sets

# Non-blocking iteration
SSCAN tags:post:1 0 COUNT 100           # Start from cursor 0
SSCAN tags:post:1 17 COUNT 100          # Continue from cursor
SSCAN tags:post:1 0 MATCH redis* COUNT 100  # With pattern filter

Use Case: Social Graph

Track followers/following relationships.

# Following relationships
SADD following:alice "bob" "charlie" "dave"
SADD following:bob "alice" "eve"
SADD followers:bob "alice" "charlie"

# Find mutual follows (who both Alice and Bob follow)
SINTER following:alice following:bob

# Find all people in extended network
SUNION following:alice following:bob

# Check if Alice follows Bob
SISMEMBER following:alice "bob"

# Get follow counts
SCARD following:alice                   # Following count
SCARD followers:alice                   # Followers count

Use Case: Unique Visitors

# Track daily unique visitors
today = "2024-01-15"

def track_visitor(visitor_id):
    key = f"visitors:{today}"
    SADD(key, visitor_id)
    EXPIRE(key, 86400 * 7)  # Keep for 7 days

def get_unique_count(date):
    return SCARD(f"visitors:{date}")

def get_weekly_uniques():
    keys = [f"visitors:{day}" for day in last_7_days()]
    temp_key = "visitors:week:temp"
    SUNIONSTORE(temp_key, *keys)
    count = SCARD(temp_key)
    DEL(temp_key)
    return count

Use Case: Tagging System

# Tag posts
SADD post:123:tags "redis" "tutorial" "database"
SADD post:456:tags "redis" "performance" "caching"

# Reverse index: posts by tag
SADD tag:redis:posts "123" "456"
SADD tag:tutorial:posts "123"

# Find posts with multiple tags
SINTER tag:redis:posts tag:tutorial:posts

# Find all posts with any of these tags
SUNION tag:redis:posts tag:caching:posts

Use Case: Random Giveaway

# Add participants
SADD giveaway:123 "user:1" "user:2" "user:3" "user:4" "user:5"

# Pick winner (removes from set)
winner = SPOP giveaway:123
print(f"Winner: {winner}")

# Pick 3 winners
winners = SPOP giveaway:123 3

# Preview random participants without removing
preview = SRANDMEMBER giveaway:123 5
Knowledge is power.