Redis many to many

In SQL world the Many-To-Many relationship is one of the most common problem. In SQL world the solution is to use relation table which describes relationship between objects. Let's imagine that we have two things in our app: users and groups. User can belong into multiple groups and group can contain multiple users. This is classical many-to-many situation, which is solved by placing relation table between user and group.

When user is attached to group we can just add a line into UserGroup table and when user is detached from group we simply delete the line.

Many-To-Many in Redis

Lets say we but users and groups into own sets (like rows in sql). User 1 data is stored in a key called User:1, Group 1 data into Group:1 and so forth.

Then we store a relations between users and groups in a Set (http://redis.io/commands#set).
Key is user+id and members are groups with their ids:

User:1
 + Group:1
 + Group:2

User:2
 + Group2

Now we could fetch all the user groups with simple redis command:
smembers User:1

This gives us a nice list of groups where this user belongs to, but what if we want to get all users which belongs to group 2? We have to enumerate through all users and look up for member Group:2. This is time consuming and not very efficient.

To solve this problem we can use two different sets to keep track of relations.

First we store users and groups into sets.
Then we store relations into two separate hash "structures". First one contains User -> Group relations and second contains Group -> User relations.



Let's say that User 1 joins into Group 2. We will add "Group:2" hash member into "User:1" hash. Then we will add "User:1" hash member into "Group:2" hash.

In redis command this would go like this (notice the key):
sadd GroupsOfUser:1 Group:2
sadd UsersOfGroup:2 User:1

Now we can fetch all the users that are in Group 2 by using command:
smembers UsersOfGroup:2

Or all the groups of User 1.
smembers GroupsOfUser:1

But Redis is not a relational database

Redis is not a relational database, because you cannot have keys referring each others. Redis is a NoSQL database which needs a different kind of mindset than regular SQL database.

For example we can store group info inside users and inside groups.

User hash can contain groups in one or in multiple member (Group:1, Group:2). I prefer one member because its easier to fetch all the groups with one simple command.

Example in redis commands:
hmset User:1 Groups 1,2  (Store user to database)
hmset Group1 Users 1      (Store group to database)

Get User 1 groups:
hget User:1 Groups

Remove user from group:
hmset User:1 Group ""
hmset Group:1 Users: ""

This requires some application logic to parse group information from comma separated string and build a proper update clause, but thats easy application logic which can be unit tested and reused in other places.



2 comments:

  1. I do agree with all the ideas you have presented in your post. They’re really convincing and will certainly work. Still, the posts are very short for newbies. Could you please extend them a little from next time?..Keep this great work
    Web development Company in India Company | Web development Company Bangalore
    Web Development Company in Bangalore | Responsive Web development

    ReplyDelete

  2. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Online Training from India. or learn thru ASP.NET Essential Training Online . Nowadays Dot Net has tons of job opportunities on various vertical industry.
    JavaScript Online Training from India

    ReplyDelete