0% found this document useful (0 votes)
37 views5 pages

Storing User Data in Redis Hashes and Sets

This document discusses using Redis hashes and sets to store user and circle data. Hashes are used to store user profile fields like name, email, phone number, and visits. Sets are used to represent circles, with members added using SADD and retrieved with SMEMBERS. Intersecting and union operations on circles are demonstrated.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views5 pages

Storing User Data in Redis Hashes and Sets

This document discusses using Redis hashes and sets to store user and circle data. Hashes are used to store user profile fields like name, email, phone number, and visits. Sets are used to represent circles, with members added using SADD and retrieved with SMEMBERS. Intersecting and union operations on circles are demonstrated.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

This way we guarantee that the user always sees real live counter data when looking at

the page, and that his own visited is counted too—all with a single Redis command.

Storing object data in hashes


As discussed in “Using Redis Data Types” on page 7, Redis’s implementation of hashes
makes for a perfect solution to store the object data applications typically use. In the
following example, we’ll look into how we might use hashes to store information on
users in a given system.
We’ll begin by designing a key namespace to store our users. As before, we’ll be sepa-
rating keywords with colons to generate a rich key that makes sense in our system. For
the sake of this recipe, we’ll go with something simple like keys in the form of
users:alias, where alias is a binary-safe string. So to store information about a user
called John Doe, we might build a hash called users:jdoe.
Let’s also assume we want to store a number of fields about our users, such as a full
name, email address, phone number, and number of visits to our application. We’ll
use Redis’s hash management commands—like HSET, HGET, and HINCRBY—to store this
information.

redis> hset users:jdoe name "John Doe"


(integer) 1
redis> hset users:jdoe email "[email protected]"
(integer) 1
redis> hset users:jdoe phone "+1555313940"
(integer) 1
redis> hincrby users:jdoe visits 1
(integer) 1

With our hash built and in place, we can fetch single fields with HGET or the full hash
by using the HGETALL command, as exemplified here:

redis> hget users:jdoe email


"[email protected]"
redis> hgetall users:jdoe
1) "name"
2) "John Doe"
3) "email"
4) "[email protected]"
5) "phone"
6) "+1555313940"
7) "visits"
8) "1"

Using Redis as a Key/Value Store | 17

www.it-ebooks.info
There are auxiliary commands like HKEYS, which return the keys stored in a particular
hash, and HVALS, which returns only the values. Depending on how you want to retrieve
your data, you may find it useful to use HGETALL or one of these to retrieve data from
Redis into your application.

redis> hkeys users:jdoe


1) "name"
2) "email"
3) "phone"
4) "visits"
redis> hvals users:jdoe
1) "John Doe"
2) "[email protected]"
3) "+1555313940"
4) "1"

For a list of additional commands to manage our users hash, peruse the Redis official
documentation for hash commands, which includes its own set of examples on man-
aging data with hashes.

Storing user “Circles” using sets


To complete our look at some typical ways to store data in Redis, let’s look at how we
can use Redis’s support for sets to create functionality similar to the circles in the
recently launched Google+. Sets are a natural fit for circles, because sets represent
collections of data, and have native functionality to do interesting things like intersec-
tions and unions.
Let’s begin by defining a namespace for our circles. We want to store several circles for
each of our users, so it makes sense for our key to include a bit about the user and a bit
about the actual circle. As an example, John Doe’s family circle might have a key like
circle:jdoe:family. Similarly, his soccer practice buddies might be listed in a set with
the key circle:jdoe:soccer. There’s no set rule for key design, so always design them
in a way that is meaningful to your application.
Now that we know which keys to store our sets in, let’s create John Doe’s family and
soccer practice sets. Inside the set itself, we can list anything from user IDs to references
to other keys in Redis, so we’ll do the latter because it makes sense for us. This way if
we want to grab a list of users that belong to John’s family circle and show information
about them, we can use the result of our set operation to then grab the actual hashes
for each user (which might be stored as described in the previous section).

redis> sadd circle:jdoe:family users:anna


(integer) 1
redis> sadd circle:jdoe:family users:richard

18 | Chapter 3: Leveraging Redis

www.it-ebooks.info
(integer) 1
redis> sadd circle:jdoe:family users:mike
(integer) 1
redis> sadd circle:jdoe:soccer users:mike
(integer) 1
redis> sadd circle:jdoe:soccer users:adam
(integer) 1
redis> sadd circle:jdoe:soccer users:toby
(integer) 1
redis> sadd circle:jdoe:soccer users:apollo
(integer) 1

Keep in mind that in the examples above we should be normalizing the members of
our set by using actual numbers for IDs rather than users:name. While the example
above works great, it may be a good idea for performance reasons to sacrifice a bit of
readability for more speed and memory efficiency.
Now we have a set called circle:jdoe:family with three values (in our case, these are
users:anna, users:richard, and users:mike) and a second one called circle:jdoe:soc
cer with four values (users:mike, users:adam, users:toby, and users:apollo). The val-
ues themselves are only strings, but by using strings that are meaninful to us (they’re
similar to our key design for user hashes), we can use the result of the SMEMBERS com-
mand to then get information on specific users. Here’s an example:

redis> smembers circle:jdoe:family


1) "users:richard"
2) "users:mike"
3) "users:anna"
redis> hgetall users:mike
(...)

Now that we know how to store information in sets, we can expand on this knowledge
and do interesting things like getting people who belong in both of John Doe’s sets (by
intersecting our family and soccer sets), or getting a full list of everyone John Doe has
added to circles in our system (by doing a union of John’s sets):

redis> sinter circle:jdoe:family circle:jdoe:soccer


1) "users:mike"
redis> sunion circle:jdoe:family circle:jdoe:soccer
1) "users:anna"
2) "users:mike"
3) "users:apollo"
4) "users:adam"
5) "users:richard"
6) "users:toby"

Using Redis as a Key/Value Store | 19

www.it-ebooks.info
According to our results, Mike is in both John Doe’s family and soccer circles. By doing
a union of the two circles, we also get a full list of John’s friends in our system.
As you can see, Redis’s sets make it extremely easy to do what would normally involve
a number of queries in a typical RDBMS. It also does it extremely fast, making it an
ideal candidate to implement applications that require managing (and doing operations
with) sets. Circles are one example, but things like recommendations or even text search
are also good fits for sets. We’ll look at both of these examples in depth in later recipes.

Quick Reference for Key Operations


SET key value
Sets the key to hold the given value. Existing data is overwritten (even if of a dif-
ferent data type).
GET key
Returns the content held by the key. Works only with string values.
INCR key
Increments the integer stored at key by 1.
INCRBY key value
Performs the same operation as INCR, but incrementing by value instead.
DECR key
Decrements the integer stored at key by 1.
DECRBY key value
Performs the same operation as DECR, but decrementing by value instead.

Inspecting Your Data


Problem
While developing (or perhaps debugging) with Redis, you may find you need to take a
look at your data. Even though it’s not as simple (or powerful) as MySQL’s SHOW
TABLES; and SELECT * FROM table WHERE conditions; commands, there are ways of
viewing data with Redis.

20 | Chapter 3: Leveraging Redis

www.it-ebooks.info
Solution
The Redis command that allows you to list your data is the KEYS command. Use it with
the supported wildcard matchers. Thus, the following command:
KEYS *

will return all the keys in your database. However, that is not enough, as you still may
not know what the key type is. That’s what the TYPE command is for:
TYPE keyname

This will tell you whether that key is a string, hash, list, set, or zset.

Discussion
The wildcard syntax of the KEYS command is limited but quite useful. It supports queries
like:
KEYS h*llo
Returns all keys starting in h and ending in llo.
KEYS h?llo
Returns keys that start with h, end with llo, and have exactly one character between
them.
KEYS h[ae]llo
Returns only the keys hallo and hello, if they exist.
Keep in mind that every time you use the KEYS command, Redis has to scan all the keys
in the database. Therefore, this can really slow down your server, so you probably
shouldn’t use it as a normal operation. If you need a list of all your keys (or a subset)
you might want to add those keys to a set and then query it.
Something else that might be useful if you’re debugging a running application is the
MONITOR command: it outputs the commands being sent to the server in real time.

Quick Reference for Debugging


KEYS pattern
Lists all the keys in the current database that match the given pattern.
TYPE key-name
Tells the type of the key. Possible types are: string, list, hash, set, zset, and none.
MONITOR
Outputs the commands received by the Redis server in real time.

Inspecting Your Data | 21

www.it-ebooks.info

You might also like