Databases 9 min read

Designing KV Schemas with Redis: Login System and Tag System Examples

The article explains how Redis's rich data structures enable flexible key‑value schema designs for a user login system and a tag system, contrasting them with traditional relational database approaches and demonstrating practical commands and Python code for common operations.

Architect
Architect
Architect
Designing KV Schemas with Redis: Login System and Tag System Examples

Redis's diverse data structures make its design interesting; unlike relational databases that require deep DEV‑DBA collaboration, a Redis DBA only needs to understand data structures and usage scenarios.

For a simplified user login system, the relational design stores user_id, name, login_times, and last_login_time in a single table, while the Redis design maps each column to a separate key using a colon‑separated pattern such as login:1:login_times 5 and login:1:name "ken thompson" .

Because users typically know only their usernames, an additional mapping from name to id is created, e.g., set "login:ken thompson:id" 1 . The Python login logic then retrieves the id, increments the login count, and updates the last login time using Redis commands:

uid = r.get("login:%s:id" % name)
ret = r.incr("login:%s:login_times" % uid)
ret = r.set("login:%s:last_login_time" % uid, datetime.datetime.now())

To fetch the most recent N logins, a Redis list is maintained: each login pushes the user id onto login:last_login_times and trims the list to N entries. Retrieving the list is done with r.lrange("login:last_login_times", 0, N-1) .

For ranking users by login count, a sorted set is ideal. Adding or incrementing a user's score uses r.zincrby("login:login_times", 1, uid) , and the top N users are obtained with r.zrevrange("login:login_times", 0, N-1) .

The article then compares a tag system. In a relational model, books and tags are stored in separate tables, requiring complex joins to find books with multiple tags. In Redis, book attributes are stored as simple keys, while tags are represented by sets, enabling straightforward set operations such as redis.sinter("tag:web", "tag:ruby") for books that are both web and ruby, redis.sdiff("tag:ruby", "tag:web") for ruby‑only books, and redis.sunion("tag:ruby", "tag:web") for the union.

The examples illustrate that Redis often requires fewer lines of code and eliminates the need for indexes, statistics, and execution plans that relational databases depend on, making it a compelling choice for certain OLTP scenarios where key‑value access patterns dominate.

Source: http://www.hoterran.info/redis_kv_design

RedislistDatabase ComparisonTag Systemsorted setKey-Value DesignLogin System
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.