• Gonçalo Miranda

All about Redis Hashes

Hashes are a Redis data structure type fully-featured to store more complex data. Represented as a collection of field-value pairs, they are very similar to a JSON structure.


Let's take this structure in mind:


{ "id": 1, "name": "Juniper Bonsai", "sun": "indirect", "light": "bright", "price": 1 }


To manipulate above fields we use HSET command as follow:


HSET plant:1 name "Juniper Bonsai" sun "indirect" light "bright" price 1

(integer) 4

The result returned is the total fields hashed with key plant:1.

To get different or even all parts of our hash structure we can use below commands:

HGET - retrieve value for one field

 HGET plant:1 light
"bright"

Both HGET and HSET have complexity O (1)


HGETALL - retrieve all values for all fields

> HGETALL plant:1
1) "name"
2) "Juniper Bonsai"
3) "sun"
4) "indirect"
5) "light"
6) "bright"
7) "price"
8) "1"

HSCAN - iterates over fields matching a supplied pattern (if you use * as a pattern it will return all field and values, similar to HGETALL). The syntax is the same as SCAN command.

HSCAN plant:1 0 MATCH name
1) "0"
2) 1) "name"
   2) "Juniper Bonsai"

HMGET - get values from one or more fields

HMGET plant:1 sun price
1) "indirect"
2) "1"

All these commands are O (n), where n equals the number of fields, but we should take into consideration our use cases. As an example, if we have a hash with hundred of fields and we commonly only use a small set, it is useful to run the HMGET instead of HGETALL because time complexity will be different.


Other specific commands for Hashes:

HDEL O (n) - n equals the number of fields to be deleted - delete one or more fields from a hash. Returns the number of fields deleted.

> HSET plant:1 newfield 1
(integer) 1
> HSET plant:1 othernewfield 2
(integer) 1
> HDEL plant:1 newfield othernewfield
(integer) 2

HEXISTS O (1) - checks if a field exists in the hash structure or not. Returns zero if not found and 1 if exists.

HEXISTS plant:1 newfield
(integer) 0
HEXISTS plant:1 name
(integer) 1

HINCRBY and HINCRBYFLOAT O (1) - Increments the number saved on a specific field in the hash. If the field does not exist, the command creates a new field with the value 0 and increments it.

HINCRBY plant:1 height 2
(integer) 2
HGETALL plant:1
 1) "name"
 2) "Juniper Bonsai"
 3) "sun"
 4) "indirect"
 5) "light"
 6) "bright"
 7) "water"
 8) "every 1 week"
 9) "price"
10) "2"
11) "height"
12) "2"

Common use cases for Redis hashes are

  • Rate limitings services

  • Session store

  • Store data that is schemaless and changes constantly.



Hints and Tips:

  • Fields are not stored in a specific order.

  • When a key is removed, ALL fields are removed.

  • If you want to store a JSON string instead of decomposing all JSON fields in hash fields, bear in mind that the first option will consume more memory, so it is prudent to only use it on small hashes.

  • In production environments, a hash is considered small if less than 100 fields. Therefore, use HGETALL for small hashes and HSCAN for bigger ones, because HSCAN is a non-blocking command.

  • Hashes only allow Strings. Consequently, they do not support nested objects. A strategy to overcome this scenario is by flattening relationships between fields using a name convention:

{
 "id": 1,
 "name": "Juniper Bonsai",
 "sun": "indirect",
 "light": "bright",
 "water": "every 1 week",
 "price": {
    "currency": {
       "code": "CAD",
       "description": "Canadian dollar"
    },
    "amount": "100"
 }
}

A good way to store this JSON into a hash is by separating each field by colon:

HSET plant:1 price:currency:code CAD price:currency:description "Canadian Dollar" price:amount 100
(integer) 3
HGETALL plant:1
 1) "name"
 2) "Juniper Bonsai"
 3) "sun"
 4) "indirect"
 5) "light"
 6) "bright"
 7) "water"
 8) "every 1 week"
 9) "price"
10) "2"
11) "height"
12) "2"
13) "price:currency:code"
14) "CAD"
15) "price:currency:description"
16) "Canadian Dollar"
17) "price:amount"
18) "100"


Thank you


6 views0 comments

Recent Posts

See All