dot Become a Redis expert.

See what's new in Redis University

3.4 Hashes

back to home

3.4 Hashes

As introduced in chapter 1, HASHes in Redis allow you to store groups of key-value pairs in a single higher-level Redis key. Functionally, the values offer some of the same features as values in STRINGs and can be useful to group related data together. This data grouping can be thought of as being similar to a row in a relational database or a document in a document store.

In this section, we’ll talk about the most commonly used commands that manipulate HASHes. You’ll learn more about the operations for adding and removing key-value pairs to HASHes, as well as commands to fetch all of the HASH contents along with the ability to increment or decrement values. When finished with this section, you’ll better understand the usefulness of storing your data in HASHes and how to do so. Look at table 3.7 to see some commonly used HASH commands.

Table 3.7 Operations for adding and removing items from HASHes
Command Example use and description
HMGET HMGET key-name key [key …] — Fetches the values at the fields in the HASH
HMSET HMSET key-name key value [key value …] — Sets the values of the fields in the HASH
HDEL HDEL key-name key [key …] — Deletes the key-value pairs in the HASH, returning the number of pairs that were found and deleted
HLEN HLEN key-name — Returns the number of key-value pairs in the HASH

Some of those commands should be familiar from chapter 1, but we have a couple of new ones for getting and setting multiple keys at the same time. These bulk commands are mostly a matter of convenience and to improve Redis’s performance by reducing the number of calls and round trips between a client and Redis. Look at the next listing to see some of them in action.

Listing 3.7 A sample interaction showing some common HASH commands in Redis
>>> conn.hmset('hash-key', {'k1':'v1', 'k2':'v2', 'k3':'v3'})
True

We can add multiple items to the hash in one call.

>>> conn.hmget('hash-key', ['k2', 'k3'])
['v2', 'v3']

We can fetch a subset of the values in a single call.

>>> conn.hlen('hash-key')
3

The HLEN command is typically used for debugging very large HASHes.

>>> conn.hdel('hash-key', 'k1', 'k3')
True

The HDEL command handles multiple arguments without needing an HMDEL counterpart and returns True if any fields were removed.

The HMGET/HMSET commands are similar to their single-argument versions that we introduced in chapter 1, only differing in that they take a list or dictionary for arguments instead of the single entries.

Table 3.8 shows some other bulk commands and more STRING-like operations on HASHes.

With the availability of HGETALL, it may not seem as though HKEYS and HVALUES would be that useful, but when you expect your values to be large, you can fetch the keys, and then get the values one by one to keep from blocking other requests.

Table 3.8 More bulk operations and STRING-like calls over HASHes
Command Example use and description
HEXISTS HEXISTS key-name key — Returns whether the given key exists in the HASH
HKEYS HKEYS key-name — Fetches the keys in the HASH
HVALS HVALS key-name — Fetches the values in the HASH
HGETALL HGETALL key-name — Fetches all key-value pairs from the HASH
HINCRBY HINCRBY key-name key increment — Increments the value stored at the given key by the integer increment
HINCRBYFLOAT HINCRBYFLOAT key-name key increment — Increments the value stored at the given key by the float increment

HINCRBY and HINCRBYFLOAT should remind you of the INCRBY and INCRBYFLOAT operations available on STRING keys, and they have the same semantics, applied to HASH values. Let’s look at some of these commands being used in the next listing.

Listing 3.8 A sample interaction showing some more advanced features of Redis HASHes
>>> conn.hmset('hash-key2', {'short':'hello', 'long':1000*'1'})
True
>>> conn.hkeys('hash-key2')
['long', 'short']

Fetching keys can be useful to keep from needing to transfer large values when we’re looking into HASHes.

>>> conn.hexists('hash-key2', 'num')
False

We can also check the existence of specific keys.

>>> conn.hincrby('hash-key2', 'num')
1L
>>> conn.hexists('hash-key2', 'num')
True

Incrementing a previously nonexistent key in a hash behaves just like on strings; Redis operates as though the value had been 0.

As we described earlier, when confronted with a large value in a HASH, we can fetch the keys and only fetch values that we’re interested in to reduce the amount of data that’s transferred. We can also perform key checks, as we could perform member checks on SETs with SISMEMBER. And back in chapter 1, we used HINCRBY to keep track of the number of votes an article had received, which we just revisited.

Let’s look at a structure that we’ll be using fairly often in the remaining chapters: sorted sets.