KAHIBARO
Discord Login Register

16.3.3. Keys and Values

Understanding Keys and Values in Redis

Redis is a key value store, so everything starts with understanding what a key is and what a value is. Even when you later work with lists, sets, hashes, and more complex data, they are still stored under keys.

In this chapter you will learn how keys and values work in Redis, how to choose good keys, and how to store and retrieve data.


What Is a Key in Redis?

A key in Redis is a string that uniquely identifies a piece of data. You can think of it as a variable name or as a row primary key in a database, but it is always a string.

Some examples of valid keys:

text
"user:1"
"session:abc123"
"cart:42"
"config:site_name"
"counter:visits"

Keys:

Basic rule:

Each Redis key maps to exactly one value at a time.


What Is a Value in Redis?

A value is the data stored under a key. In Redis, values can be of different types, such as:

In this chapter we focus on the idea of key and value in general, and especially on string values, since many commands work with strings.

Examples:

Even numbers are stored as strings by default. Redis can interpret some string values as integers for operations like INCR, but they are still stored as strings.


Basic Key Value Commands

The most important commands for simple key value operations are:

SET: Store a Value

SET saves a value under a key.

bash
SET user:1:name "Alice"
SET user:1:age "30"

You can also store numbers as strings:

bash
SET counter:visits "0"

GET: Retrieve a Value

GET returns the value stored under a key.

bash
GET user:1:name
# "Alice"
GET user:1:age
# "30"

If the key does not exist, GET returns a special null reply:

bash
GET user:2:name
# (nil)   (means "no value")

EXISTS: Check If a Key Exists

EXISTS tells you if a key is present.

bash
EXISTS user:1:name
# (integer) 1   (exists)
EXISTS user:2:name
# (integer) 0   (does not exist)

DEL: Delete Keys

DEL removes one or more keys and their values.

bash
DEL user:1:name
DEL user:1:age

DEL returns how many keys were removed:

bash
DEL user:1:name user:1:age
# (integer) 2

If you delete a key, the value is gone and memory is freed.


Key Naming Conventions

Choosing good key names is very important in Redis. There are no tables or schemas, so key names are your main way to organize data.

Common Pattern: Use `:` as a Separator

Most Redis users follow a convention similar to:

text
<namespace>:<object_type>:<id>:<field>

Examples:

This is not mandatory, but it makes keys:

Examples of Good vs Bad Key Names

PurposeGood key nameBad key nameWhy good?
User name for id 1user:1:namename1Clear model and id
User email for id 12user:12:emailu12eEasy to read, no guesswork
Shopping cart for user 5cart:user:5cart5Contains both cart and user in name
Global page view countercounter:page_viewspvIndicates purpose clearly
Feature flag: new_checkoutfeature:new_checkoutflag1Meaningful name, easy to search/filter

Avoiding Key Collisions

If you mix different types of data, you must name keys carefully to avoid collisions.

Bad:

bash
SET user:1 "Alice"
SET user:1 "something else"  # Overwrites the previous value

Better:

bash
SET user:1:name "Alice"
SET user:1:age "30"

Or store structured data under a single key using another type (this is covered in the data structures chapter).


Key Length and Limits

Redis allows keys up to 512 MB in length, but you should not use very long keys.

Practical guidelines:

Bad:

text
"user:{"id":1,"name":"Alice","email":"alice@example.com"}"

Good:

text
"user:1"

Where the value contains the data (as a string, JSON, hash, etc).


Working With Numeric Values

Even though Redis stores values as strings, you often want to work with numbers. Redis provides atomic operations for integer values.

INCR and DECR

INCR increases a numeric value by 1. Redis interprets the value as an integer.

bash
SET counter:visits "0"
INCR counter:visits
# (integer) 1
INCR counter:visits
# (integer) 2
GET counter:visits
# "2"

DECR decreases by 1:

bash
DECR counter:visits
# (integer) 1

**The value must be a valid integer string, such as "0", "42", or "-5".
If the value is not an integer string, commands like INCR will fail.**

Example of an error:

bash
SET counter:visits "hello"
INCR counter:visits
# (error) ERR value is not an integer or out of range

INCRBY and DECRBY

You can change a numeric value by more than 1:

bash
SET counter:downloads "10"
INCRBY counter:downloads 5
# (integer) 15
DECRBY counter:downloads 3
# (integer) 12

Example: Implementing a Simple Page View Counter

Imagine you want to count how many times a page is viewed.

Each time a user opens the page:

bash
INCR counter:page:home

To display the count:

bash
GET counter:page:home
# "123"

In code (Python with redis-py style client):

python
import redis
r = redis.Redis(host="localhost", port=6379, db=0)
def track_page_view(page_id: str) -> int:
    key = f"counter:page:{page_id}"
    new_value = r.incr(key)  # INCR command
    return new_value
views = track_page_view("home")
print("Home page views:", views)

Key Expiration and Temporary Values

Sometimes you want a key to exist only for a limited time, for example for a login session, a password reset token, or a cache entry.

Redis supports key expiration. After a certain time, the key is automatically deleted.

SET with EX

You can set a key with a time to live in seconds:

bash
SET session:abc123 "user:1" EX 60

This creates session:abc123 which will live for 60 seconds.

After 60 seconds:

bash
GET session:abc123
# (nil)

You can use PX for milliseconds:

bash
SET temp:code "123456" PX 300000   # 5 minutes

EXPIRE Command

You can set or change expiration after creating a key:

bash
SET session:abc123 "user:1"
EXPIRE session:abc123 120   # 120 seconds

EXPIRE returns 1 if the timeout was set, 0 if the key does not exist.

Check remaining time to live with TTL:

bash
TTL session:abc123
# (integer) 97   (seconds left)

**When a key expires, it is automatically deleted and cannot be recovered.
Always handle the case where an expected key no longer exists.**


Listing and Searching Keys

For learning and testing, you might want to see what keys exist.

KEYS (for development only)

KEYS lets you search for keys that match a pattern:

bash
KEYS *
# lists all keys
KEYS "user:*"
# lists all keys starting with "user:"
KEYS "session:*:user*"
# lists keys matching the pattern

Patterns use glob style wildcards:

PatternMeaning
*Match any number of characters
?Match any single character
[abc]Match any one character in the set

However:

**Never use KEYS in production on large databases.
It can block Redis while scanning all keys.
Use SCAN instead for production systems.**

SCAN is more advanced and covered elsewhere. For now, just know that KEYS is fine for a small local instance when learning.


Overwriting and Replacing Values

Since each key maps to one value, if you call SET multiple times with the same key, Redis always stores the latest value.

Example:

bash
SET user:1:name "Alice"
GET user:1:name
# "Alice"
SET user:1:name "Bob"
GET user:1:name
# "Bob"

You can also control overwriting behavior:

SETNX: Set Only If Not Exists

SETNX means "SET if Not eXists":

bash
SETNX config:site_name "MySite"
# (integer) 1   (key created)
SETNX config:site_name "OtherSite"
# (integer) 0   (key already exists, not changed)
GET config:site_name
# "MySite"

This is useful when you want to initialize settings or create locks without overwriting existing data.


Practical Key and Value Patterns

1. Caching Example

Imagine you have a slow database query to get a product by id.

You can cache the result:

Commands:

bash
SET cache:product:42 '{"id":42,"name":"Phone","price":299}' EX 60
GET cache:product:42

In code:

python
def get_product_cached(product_id: int):
    key = f"cache:product:{product_id}"
    cached = r.get(key)
    if cached is not None:
        return cached  # in real code, decode JSON
    # simulate slow database query
    product = {"id": product_id, "name": "Phone", "price": 299}
    r.set(key, json.dumps(product), ex=60)
    return product

2. Session Example

For user sessions after login:

bash
SET session:abc123 "user:1" EX 3600
GET session:abc123
# "user:1"

3. Feature Flags Example

To control features in your app:

bash
SET feature:new_checkout "on"
GET feature:new_checkout
# "on"

Inspecting Key Types

As mentioned, Redis values can be different types. To see the type of a given key, use TYPE:

bash
SET user:1:name "Alice"
TYPE user:1:name
# string
LPUSH user:1:logins "2024-01-01"
TYPE user:1:logins
# list

This is useful when debugging your data model.

**Do not mix different types under the same key.
If a key is used as a string, do not later use list commands on it.
Always keep one key associated with one consistent type.**


Summary

In Redis, everything starts with keys and values:

With these basics, you can model many common backend problems, such as counters, sessions, and caches, using Redis keys and values.

Views: 6

Comments

Please login to add a comment.

Don't have an account? Register now!