Chapter 3: Data Types and Operations
Authored by syscook.dev
What are Redis Data Types and Operations?
Redis supports various data types, each optimized for specific use cases. Understanding these data types and their operations is crucial for building efficient Redis applications. Each data type has its own set of commands and use cases.
Key Data Types:
- Strings: Simple key-value pairs, counters, bitmaps
- Hashes: Field-value mappings, object storage
- Lists: Ordered collections, queues, stacks
- Sets: Unordered unique collections, tags, relationships
- Sorted Sets: Ordered unique collections with scores, rankings
- Streams: Log-like data structures, event sourcing
- Bitmaps: Bit-level operations, analytics
- HyperLogLogs: Probabilistic cardinality estimation
Why Use Different Data Types?
1. Strings for Simple Storage and Counters
Strings are the most basic Redis data type, perfect for simple key-value storage and atomic operations.
# Basic string operations
127.0.0.1:6379> SET user:1001:name "John Doe"
OK
127.0.0.1:6379> GET user:1001:name
"John Doe"
127.0.0.1:6379> STRLEN user:1001:name
(integer) 8
# Counter operations
127.0.0.1:6379> SET page_views 0
OK
127.0.0.1:6379> INCR page_views
(integer) 1
127.0.0.1:6379> INCRBY page_views 10
(integer) 11
127.0.0.1:6379> DECR page_views
(integer) 10
# Bitmap operations
127.0.0.1:6379> SETBIT user:1001:online 0 1
(integer) 0
127.0.0.1:6379> SETBIT user:1001:online 1 1
(integer) 0
127.0.0.1:6379> GETBIT user:1001:online 0
(integer) 1
127.0.0.1:6379> BITCOUNT user:1001:online
(integer) 2
String Use Cases:
- Simple key-value storage
- Counters and statistics
- Caching
- Bitmap operations for analytics
- Session storage
2. Hashes for Object Storage
Hashes are perfect for storing objects with multiple fields, providing efficient storage and retrieval.
# Hash operations
127.0.0.1:6379> HSET user:1001 name "John Doe" email "[email protected]" age 30
(integer) 3
127.0.0.1:6379> HGET user:1001 name
"John Doe"
127.0.0.1:6379> HGETALL user:1001
1) "name"
2) "John Doe"
3) "email"
4) "[email protected]"
5) "age"
6) "30"
# Hash field operations
127.0.0.1:6379> HKEYS user:1001
1) "name"
2) "email"
3) "age"
127.0.0.1:6379> HVALS user:1001
1) "John Doe"
2) "[email protected]"
3) "30"
127.0.0.1:6379> HEXISTS user:1001 name
(integer) 1
127.0.0.1:6379> HDEL user:1001 age
(integer) 1
127.0.0.1:6379> HINCRBY user:1001 age 1
(integer) 31
Hash Use Cases:
- Object storage
- User profiles
- Configuration storage
- Field-level updates
- Efficient memory usage for objects
3. Lists for Ordered Collections
Lists provide ordered collections that can be used as queues, stacks, or simple lists.
# List operations
127.0.0.1:6379> LPUSH tasks "task1" "task2" "task3"
(integer) 3
127.0.0.1:6379> LRANGE tasks 0 -1
1) "task3"
2) "task2"
3) "task1"
127.0.0.1:6379> RPUSH tasks "task4"
(integer) 4
127.0.0.1:6379> LPOP tasks
"task3"
127.0.0.1:6379> RPOP tasks
"task4"
# List management
127.0.0.1:6379> LLEN tasks
(integer) 2
127.0.0.1:6379> LINDEX tasks 0
"task2"
127.0.0.1:6379> LINSERT tasks BEFORE "task2" "newtask"
(integer) 3
127.0.0.1:6379> LREM tasks 1 "task2"
(integer) 1
List Use Cases:
- Task queues
- Message queues
- Recent items lists
- Stacks and queues
- Timeline feeds
4. Sets for Unique Collections
Sets store unique elements and provide set operations like union, intersection, and difference.
# Set operations
127.0.0.1:6379> SADD tags "redis" "database" "cache" "nosql"
(integer) 4
127.0.0.1:6379> SMEMBERS tags
1) "nosql"
2) "cache"
3) "database"
4) "redis"
127.0.0.1:6379> SISMEMBER tags "redis"
(integer) 1
127.0.0.1:6379> SCARD tags
(integer) 4
# Set operations with multiple sets
127.0.0.1:6379> SADD tags2 "redis" "python" "web"
(integer) 3
127.0.0.1:6379> SINTER tags tags2
1) "redis"
127.0.0.1:6379> SUNION tags tags2
1) "nosql"
2) "cache"
3) "database"
4) "redis"
5) "python"
6) "web"
127.0.0.1:6379> SDIFF tags tags2
1) "nosql"
2) "cache"
3) "database"
# Random operations
127.0.0.1:6379> SRANDMEMBER tags
"cache"
127.0.0.1:6379> SPOP tags
"nosql"
Set Use Cases:
- Tag systems
- Unique user tracking
- Set operations (union, intersection, difference)
- Random sampling
- Relationship modeling
5. Sorted Sets for Rankings
Sorted sets combine the uniqueness of sets with ordering by scores, perfect for rankings and leaderboards.
# Sorted set operations
127.0.0.1:6379> ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
(integer) 3
127.0.0.1:6379> ZRANGE leaderboard 0 -1 WITHSCORES
1) "player1"
2) "100"
3) "player3"
4) "150"
5) "player2"
6) "200"
# Ranking operations
127.0.0.1:6379> ZRANK leaderboard "player2"
(integer) 2
127.0.0.1:6379> ZREVRANK leaderboard "player2"
(integer) 0
127.0.0.1:6379> ZSCORE leaderboard "player1"
"100"
127.0.0.1:6379> ZCOUNT leaderboard 100 200
(integer) 3
# Score operations
127.0.0.1:6379> ZINCRBY leaderboard 50 "player1"
"150"
127.0.0.1:6379> ZRANGEBYSCORE leaderboard 100 200
1) "player1"
2) "player3"
3) "player2"
127.0.0.1:6379> ZREMRANGEBYRANK leaderboard 0 0
(integer) 1
Sorted Set Use Cases:
- Leaderboards
- Rankings
- Time-series data
- Priority queues
- Range queries
How to Use Redis Data Types?
1. String Operations
Basic String Commands
# Set and get operations
SET key value
GET key
SETEX key seconds value
SETNX key value
MSET key1 value1 key2 value2
MGET key1 key2
# String manipulation
APPEND key value
STRLEN key
GETRANGE key start end
SETRANGE key offset value
# Numeric operations
INCR key
INCRBY key increment
DECR key
DECRBY key decrement
INCRBYFLOAT key increment
Advanced String Operations
# Bitmap operations
SETBIT key offset value
GETBIT key offset
BITCOUNT key [start end]
BITOP operation destkey key [key ...]
BITPOS key bit [start] [end]
# Example: User activity tracking
SETBIT user:1001:activity 0 1 # Day 1 active
SETBIT user:1001:activity 1 1 # Day 2 active
SETBIT user:1001:activity 2 0 # Day 3 inactive
BITCOUNT user:1001:activity # Count active days
2. Hash Operations
Hash Field Management
# Basic hash operations
HSET key field value
HGET key field
HGETALL key
HDEL key field [field ...]
HEXISTS key field
HKEYS key
HVALS key
HLEN key
# Hash field operations
HINCRBY key field increment
HINCRBYFLOAT key field increment
HMSET key field1 value1 field2 value2
HMGET key field1 field2
HSETNX key field value
Hash Use Cases
# User profile storage
HSET user:1001 name "John Doe" email "[email protected]" age 30
HGET user:1001 name
HINCRBY user:1001 age 1
# Configuration storage
HSET config:app database_url "postgres://..." cache_ttl 3600
HGET config:app database_url
# Session storage
HSET session:abc123 user_id 1001 login_time "2024-01-15T10:30:00Z"
HGETALL session:abc123
3. List Operations
List Manipulation
# Basic list operations
LPUSH key element [element ...]
RPUSH key element [element ...]
LPOP key
RPOP key
LLEN key
LRANGE key start stop
LINDEX key index
LINSERT key BEFORE|AFTER pivot element
# List management
LREM key count element
LTRIM key start stop
LSET key index element
List Use Cases
# Task queue (FIFO)
LPUSH task_queue "task1" "task2" "task3"
RPOP task_queue # Process tasks in order
# Recent items
LPUSH recent_items "item1" "item2" "item3"
LTRIM recent_items 0 9 # Keep only 10 most recent
# Message queue
LPUSH messages "msg1" "msg2"
RPOP messages # Process messages
4. Set Operations
Set Management
# Basic set operations
SADD key member [member ...]
SREM key member [member ...]
SMEMBERS key
SISMEMBER key member
SCARD key
SRANDMEMBER key [count]
SPOP key [count]
# Set operations
SINTER key [key ...]
SUNION key [key ...]
SDIFF key [key ...]
SINTERSTORE destination key [key ...]
SUNIONSTORE destination key [key ...]
SDIFFSTORE destination key [key ...]
Set Use Cases
# Tag system
SADD post:123:tags "redis" "database" "tutorial"
SADD post:456:tags "redis" "python" "web"
SINTER post:123:tags post:456:tags # Common tags
# User tracking
SADD unique_visitors "user1" "user2" "user3"
SCARD unique_visitors # Count unique visitors
# Friend relationships
SADD user:1001:friends "user2" "user3" "user4"
SADD user:1002:friends "user1" "user3" "user5"
SINTER user:1001:friends user:1002:friends # Mutual friends
5. Sorted Set Operations
Sorted Set Management
# Basic sorted set operations
ZADD key score member [score member ...]
ZREM key member [member ...]
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
ZRANK key member
ZREVRANK key member
ZSCORE key member
ZCARD key
# Score-based operations
ZCOUNT key min max
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
ZREMRANGEBYRANK key start stop
ZREMRANGEBYSCORE key min max
ZINCRBY key increment member
Sorted Set Use Cases
# Leaderboard
ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
ZREVRANGE leaderboard 0 9 WITHSCORES # Top 10 players
# Time-series data
ZADD events 1642248000 "event1" 1642248060 "event2"
ZRANGEBYSCORE events 1642248000 1642248100 # Events in time range
# Priority queue
ZADD priority_queue 1 "low_priority_task" 5 "high_priority_task"
ZPOPMAX priority_queue # Get highest priority task
Practical Examples
1. E-commerce Application
Product Catalog with Hashes
#!/bin/bash
# ecommerce-example.sh
# Store product information
redis-cli HSET product:1001 name "Laptop" price 999.99 category "Electronics" stock 50
redis-cli HSET product:1002 name "Mouse" price 29.99 category "Electronics" stock 100
redis-cli HSET product:1003 name "Book" price 19.99 category "Books" stock 200
# Get product details
redis-cli HGETALL product:1001
# Update stock
redis-cli HINCRBY product:1001 stock -1
# Check stock
redis-cli HGET product:1001 stock
Shopping Cart with Hashes
#!/bin/bash
# shopping-cart-example.sh
# Add items to cart
redis-cli HSET cart:user:1001 product:1001 2
redis-cli HSET cart:user:1001 product:1002 1
redis-cli HSET cart:user:1001 product:1003 3
# Get cart contents
redis-cli HGETALL cart:user:1001
# Update quantity
redis-cli HINCRBY cart:user:1001 product:1001 1
# Remove item
redis-cli HDEL cart:user:1001 product:1002
# Clear cart
redis-cli DEL cart:user:1001
2. Social Media Application
User Relationships with Sets
#!/bin/bash
# social-media-example.sh
# Add friends
redis-cli SADD user:1001:friends "user2" "user3" "user4"
redis-cli SADD user:1002:friends "user1" "user3" "user5"
redis-cli SADD user:1003:friends "user1" "user2" "user6"
# Find mutual friends
redis-cli SINTER user:1001:friends user:1002:friends
# Find all friends
redis-cli SUNION user:1001:friends user:1002:friends
# Check if users are friends
redis-cli SISMEMBER user:1001:friends "user2"
# Remove friend
redis-cli SREM user:1001:friends "user4"
Post Tags with Sets
#!/bin/bash
# post-tags-example.sh
# Add tags to posts
redis-cli SADD post:123:tags "redis" "database" "tutorial"
redis-cli SADD post:456:tags "redis" "python" "web"
redis-cli SADD post:789:tags "database" "sql" "tutorial"
# Find posts with common tags
redis-cli SINTER post:123:tags post:456:tags
# Find all unique tags
redis-cli SUNION post:123:tags post:456:tags post:789:tags
# Count tags per post
redis-cli SCARD post:123:tags
3. Gaming Application
Leaderboard with Sorted Sets
#!/bin/bash
# gaming-leaderboard-example.sh
# Add players to leaderboard
redis-cli ZADD leaderboard 1000 "player1" 1500 "player2" 1200 "player3" 2000 "player4"
# Get top 10 players
redis-cli ZREVRANGE leaderboard 0 9 WITHSCORES
# Get player rank
redis-cli ZREVRANK leaderboard "player2"
# Update player score
redis-cli ZINCRBY leaderboard 100 "player1"
# Get players in score range
redis-cli ZRANGEBYSCORE leaderboard 1000 1500 WITHSCORES
# Remove player
redis-cli ZREM leaderboard "player3"
Player Statistics with Hashes
#!/bin/bash
# player-stats-example.sh
# Store player statistics
redis-cli HSET player:1001 level 25 experience 15000 gold 5000 wins 45 losses 12
redis-cli HSET player:1002 level 30 experience 25000 gold 8000 wins 60 losses 8
redis-cli HSET player:1003 level 20 experience 12000 gold 3000 wins 35 losses 15
# Get player stats
redis-cli HGETALL player:1001
# Update experience
redis-cli HINCRBY player:1001 experience 1000
# Check if player has enough gold
redis-cli HGET player:1001 gold
Best Practices
1. Choose the Right Data Type
# For simple key-value: Use strings
SET user:1001:name "John Doe"
# For objects: Use hashes
HSET user:1001 name "John Doe" email "[email protected]"
# For lists: Use lists
LPUSH tasks "task1" "task2"
# For unique items: Use sets
SADD tags "redis" "database"
# For rankings: Use sorted sets
ZADD leaderboard 100 "player1"
2. Optimize Memory Usage
# Use hashes for objects instead of JSON strings
HSET user:1001 name "John" email "[email protected]"
# Use appropriate data structures
# For counters: Use INCR instead of GET + SET
INCR page_views
# For unique items: Use sets
SADD unique_visitors "user123"
3. Use Atomic Operations
# Use atomic operations for consistency
INCR counter
HINCRBY user:1001 score 10
ZINCRBY leaderboard 50 "player1"
# Use transactions for multiple operations
MULTI
SET key1 value1
SET key2 value2
EXEC
Common Pitfalls and Solutions
1. Wrong Data Type Choice
# ❌ Bad: Using strings for objects
SET user:1001 '{"name":"John","email":"[email protected]"}'
# ✅ Good: Using hashes for objects
HSET user:1001 name "John" email "[email protected]"
2. Non-Atomic Operations
# ❌ Bad: Non-atomic counter update
GET counter
SET counter new_value
# ✅ Good: Atomic counter update
INCR counter
3. Memory Inefficiency
# ❌ Bad: Storing large JSON strings
SET user:1001 '{"name":"John","email":"[email protected]","age":30,"address":"123 Main St"}'
# ✅ Good: Using hashes for efficient storage
HSET user:1001 name "John" email "[email protected]" age 30 address "123 Main St"
Conclusion
Understanding Redis data types and their operations is essential for building efficient applications. By understanding:
- What different data types are and their characteristics
- Why each data type is suitable for specific use cases
- How to use operations effectively for each data type
You can choose the right data structures for your applications and optimize performance. Redis's rich set of data types and operations provides flexibility and power for a wide range of use cases.
Next Steps
- Practice with different data types and operations
- Learn about Redis persistence and replication
- Move on to Chapter 4: Persistence and Replication
This tutorial is part of the Redis Mastery series by syscook.dev