Understanding Redis Data Model
Everything you store in Redis lives under a key. The key is a name you choose, and the value attached to that key can be one of several data types. Understanding this key-value model is the foundation of everything you build with Redis.
The Dictionary Analogy
Think of Redis as a giant dictionary sitting in memory. In a dictionary, every word (key) has a definition (value). You look up the word, and the definition appears instantly.
Redis Memory (like a dictionary)
┌─────────────────────────────────────────────┐
│ │
│ "username" → "Alice" │
│ "score:101" → 9800 │
│ "cart:user5" → [item1, item2, item3] │
│ "profile:bob" → {age: 25, city: "NY"} │
│ │
└─────────────────────────────────────────────┘
▲
│
key │ value (can be different types)
Rules for Naming Keys
Redis keys are plain strings. You can name them anything, but developers follow a colon-separated naming convention to keep things organized. This is not enforced by Redis — it is a team habit that prevents confusion.
Bad key names (hard to understand):
u1, x, temp, data
Good key names (clear and organized):
user:1001:name
user:1001:email
product:42:price
session:abc123
order:2024:march:total
Pattern: type : id : field
───────────────────
user : 1001 : name
The colon is just a character — Redis gives it no special meaning. But it makes your keys readable like a file path.
The Six Main Value Types
Each key in Redis holds a value of exactly one type. You choose the type based on what you want to store.
┌──────────────┬────────────────────────────────────────────────┐ │ Value Type │ What It Stores │ ├──────────────┼────────────────────────────────────────────────┤ │ String │ Text, numbers, binary data (any single value) │ │ List │ Ordered sequence of strings (like a queue) │ │ Hash │ Map of field→value pairs (like a mini object) │ │ Set │ Unordered collection of unique strings │ │ Sorted Set │ Like a set but each item has a numeric score │ │ Stream │ Log-style append-only sequence of events │ └──────────────┴────────────────────────────────────────────────┘
A Visual Map of All Six Types
KEY: "greeting" VALUE TYPE: String
┌────────────────────────────────────┐
│ "Hello, World!" │
└────────────────────────────────────┘
KEY: "tasks" VALUE TYPE: List
┌────────────────────────────────────┐
│ ["buy milk", "read book", "code"] │
│ ← head tail → │
└────────────────────────────────────┘
KEY: "user:55" VALUE TYPE: Hash
┌────────────────────────────────────┐
│ name → "Bob" │
│ age → "29" │
│ city → "Delhi" │
└────────────────────────────────────┘
KEY: "tags" VALUE TYPE: Set
┌────────────────────────────────────┐
│ { "redis", "database", "fast" } │
│ (no duplicates, no order) │
└────────────────────────────────────┘
KEY: "leaderboard" VALUE TYPE: Sorted Set
┌────────────────────────────────────┐
│ score 500 → "Alice" │
│ score 320 → "Bob" │
│ score 180 → "Carol" │
└────────────────────────────────────┘
KEY: "events" VALUE TYPE: Stream
┌────────────────────────────────────┐
│ 1710000001-0 {action: "login"} │
│ 1710000002-0 {action: "click"} │
│ 1710000003-0 {action: "buy"} │
└────────────────────────────────────┘
How Redis Knows the Type of a Key
Redis remembers the type automatically when you create a key. You cannot store a String in a key that already holds a List — Redis rejects it with an error. Use the TYPE command to check what type a key holds:
127.0.0.1:6379> SET greeting "hello" OK 127.0.0.1:6379> TYPE greeting string 127.0.0.1:6379> LPUSH tasks "read book" (integer) 1 127.0.0.1:6379> TYPE tasks list
Namespacing Keys Across Teams
When multiple parts of an app share one Redis server, key collisions become a real problem. Two features might both want to use a key called "count" and overwrite each other's data.
Problem without namespacing: Feature A sets: count = 42 (email count) Feature B sets: count = 7 (error count) Feature A reads count → gets 7 ← WRONG! Solution with namespacing: Feature A sets: emails:count = 42 Feature B sets: errors:count = 7 No collision. Each reads its own key correctly.
Key Points
- Redis stores everything as key-value pairs, where a key is always a string.
- Use colon-separated names like user:1001:name to keep keys organized.
- Each key holds exactly one data type: String, List, Hash, Set, Sorted Set, or Stream.
- Use the TYPE command to see what type a key currently holds.
- Namespacing prevents different parts of your app from overwriting each other's keys.
