32

The think I'm trying to implement is an id table. Basically it has the structure (user_id, lecturer_id) which user_id refers to the primary key in my User table and lecturer_id refers to the primary key of my Lecturer table.

I'm trying to implement this in redis but if I set the key as User's primary id, when I try to run a query like get all the records with lecturer id=5 since lecturer is not the key, but value I won't be able to reach it in O(1) time.

How can I form a structure like the id table I mentioned in above, or Redis does not support that?

Ali
  • 5,338
  • 12
  • 55
  • 78
  • 2
    A recently added page in Redis' documentation provides more information about [Secondary indexing with Redis](http://redis.io/topics/indexes), and covers this case under the [Simple numerical indexes with sorted sets](http://redis.io/topics/indexes#simple-numerical-indexes-with-sorted-sets) section. – Itamar Haber Mar 04 '16 at 14:55

2 Answers2

38

One of the things you learn fast while working with redis is that you get to design your data structure around your accessing needs, specially when it comes to relations (it's not a relational database after all)

There is no way to search by "value" with a O(1) time complexity as you already noticed, but there are ways to approach what you describe using redis. Here's what I would recommend:

  • Store your user data by user id (in e.g. a hash) as you are already doing.
  • Have an additional set for each lecturer id containing all user ids that correspond to the lecturer id in question.

This might seem like duplicating the data of the relation, since your user data would have to store the lecture id, and your lecture data would store user ids, but that's the (tiny) price to pay if one is to build relations in a no-relational data store like redis. In practical terms this works well; memory is rarely a bottleneck for small-ish data-sets (think thousands of ids).

To get a better picture at how are people using redis to model applications with relations, I recommend reading Design and implementation of a simple Twitter clone and the source code of Lamernews, both of which are written by redis author Salvatore Sanfilippo.

Mahn
  • 16,261
  • 16
  • 62
  • 78
0

As already answered, in vanilla Redis there is no way to store the data only once and have Redis query them for you.

You have to maintain secondary indexes yourself.

However with the modules in Redis, this is not necessary true. Modules like zeeSQL, or RediSearch allow to store data directly in Redis and retrieve them with a SQL query (for zeeSQL) or simil SQL for RediSearch.

In your case, a small example with zeeSQL.

> ZEESQL.CREATE_DB DB
OK
> ZEESQL.EXEC DB COMMAND "CREATE TABLE user(user_id INT, lecture_id INT);"
OK
> ZEESQL.EXEC DB COMMAND "SELECT * FROM user WHERE lecture_id = 3;"
... your result ...
Siscia
  • 1,421
  • 1
  • 12
  • 29