Core Data Structures I: Strings, Lists, Hashes

Redis
Chapter 3 ยท Core Data Structures I: Strings, Lists, Hashes

๐Ÿงฑ Core Data Structures I: Strings, Lists, Hashes

Chapter 2's SET/GET only scratched Redis's simplest data type. Redis is really a data structure store โ€” strings, lists, hashes, and (Chapter 4) sets and sorted sets โ€” each suited to a different shape of data, all sitting behind the same simple command style.

Strings: More Than Just SET/GET

A Redis string holds a single value โ€” but beyond plain SET/GET, Redis provides INCR/DECR for atomic increments: safe to call from many concurrent clients at once with no race condition, since the increment happens as one indivisible server-side operation.

127.0.0.1:6379> SET page:home:views 0 OK 127.0.0.1:6379> INCR page:home:views (integer) 1 127.0.0.1:6379> INCR page:home:views (integer) 2

Two concurrent requests both calling INCR at the exact same instant will still produce two distinct, correct results (e.g. 1 and 2, never both landing on 1) โ€” a guarantee that would need explicit locking to replicate safely in most other systems.

Lists: Ordered Collections

A Redis list is an ordered sequence of values โ€” LPUSH inserts at the head (left/beginning), RPUSH inserts at the tail (right/end), and LRANGE reads a range of elements.

127.0.0.1:6379> RPUSH recent:activity "logged in" (integer) 1 127.0.0.1:6379> RPUSH recent:activity "viewed product 42" (integer) 2 127.0.0.1:6379> LRANGE recent:activity 0 -1 1) "logged in" 2) "viewed product 42"

LRANGE key 0 -1 is the standard idiom for "give me the whole list" โ€” 0 is the first element, -1 refers to the last element regardless of the list's length.

Hashes: Field-Value Pairs Within One Key

A Redis hash groups multiple field-value pairs under a single key โ€” the natural fit for something object-like, such as a user profile, without needing a separate top-level key per field.

127.0.0.1:6379> HSET user:104 name "Dana" email "dana@example.com" (integer) 2 127.0.0.1:6379> HGET user:104 name "Dana" 127.0.0.1:6379> HGETALL user:104 1) "name" 2) "Dana" 3) "email" 4) "dana@example.com"

Multiple String Keys vs. One Hash

Multiple Strings
SET user:104:name "Dana" SET user:104:email "dana@..."
One Hash
HSET user:104 name "Dana" email "dana@..."

The hash consolidates related fields under one key โ€” reading, updating, or deleting "this user's data" is one key to manage, not an ever-growing set of loosely related string keys sharing a naming convention.

CommandStructurePurpose
SET / GETStringStore/retrieve a single value
INCR / DECRStringAtomic increment/decrement of a numeric value
LPUSH / RPUSHListInsert at the head / tail of an ordered list
LRANGEListRead a range of elements (0 -1 = whole list)
HSET / HGETHashSet/get one field within a hash
HGETALLHashRead every field-value pair in a hash

Use a String When

The value is a single, simple piece of data โ€” a counter, a flag, a cached blob of text or serialized JSON.

Use a List When

Order matters and you're modeling a sequence โ€” a recent-activity feed, a simple queue (Chapter 7 goes deeper on this).

Use a Hash When

You're modeling one object with multiple named fields โ€” a user profile, a product record โ€” grouped under a single key.

Coming Up: Sets & Sorted Sets

Chapter 4 covers unique unordered collections and score-ordered collections โ€” leaderboards, tag systems, and more.

๐Ÿ’ป Coding Challenges

Challenge 1: Build a View Counter

Write the redis-cli commands to initialize a view counter for a page called page:about at 0, then increment it three times, showing the value after each increment.

Goal: Practice using INCR for a realistic atomic-counter scenario.

โ†’ Solution

Challenge 2: Predict List Order

Starting from an empty list queue:tasks, predict the final order of elements after running: RPUSH queue:tasks "A", RPUSH queue:tasks "B", LPUSH queue:tasks "C". Show the LRANGE command that would confirm your answer.

Goal: Practice reasoning about how LPUSH and RPUSH insert relative to each other, not just in isolation.

โ†’ Solution

Challenge 3: Model a Product as a Hash

Write the HSET command to store a product with key product:200 having fields name ("Wireless Mouse"), price ("24.99"), and category ("electronics"), then the command to read all of it back.

Goal: Practice choosing a hash over separate string keys for a naturally object-shaped record.

โ†’ Solution

โš ๏ธ Gotcha: LPUSH and RPUSH Together Reverse Relative Order

RPUSH appends to the end, in the order called โ€” repeated RPUSH calls preserve the order they were issued in. LPUSH, by contrast, inserts at the head each time โ€” so repeated LPUSH calls actually end up in reverse order relative to the sequence they were called in, since each new element pushes the previous head further right. Mixing LPUSH and RPUSH on the same list without tracking this carefully is a common source of "why is my list in the wrong order" bugs โ€” always be deliberate about which end a given piece of code pushes to, and check with LRANGE rather than assuming.

๐ŸŽฏ What's Next

The next chapter covers Sets & Sorted Sets โ€” SADD/SINTER for unique unordered collections, and ZADD/ZRANGE for score-ordered collections, including the leaderboard and sliding-window-counter patterns.