I'm trying to model data similar to amazon.com categories (e.g., books, movies, electronics, etc.) in a Redis database. Order matters to me when they're rendered on an HTML page so that the user is presented with a consistent user interface. As such, I stored the categories in a Sorted Set:
ZADD categories 0 "Books"
ZADD categories 1 "Movies"
ZADD categories 2 "Electronics"
I then created another Sorted Set for each of the sub-categories.
ZADD categories:books 0 "Fiction"
ZADD categories:books 1 "Non-Fiction"
ZADD categories:movies 0 "Horror"
[...]
From here, I figured I could store products in a Hash.
HMSET product:1000 category 0 subcategory 0 title "Redis Cookbook"
HMSET product:1001 category 1 subcategory 0 title "Nightmare on Elm Street"
[...]
I'm very new to both Redis and Key/Value database stores, so I'm anything but confident in my approach. Is this model going to work for me long-term? Is there a better/alternative approach I should be aware of? One concern I have is keeping the names "synchronized". For example, if I change the top-level category from "Books" to "Literature" (terrible example, I know) all of the keys for the sub-categories that "reference" books should also be updated.
Lets answer your question backwards.
Storing Products in a Hash
That is a good idea. In general, you want to store entities in a hashmap.
Changing Category Names
You should use an internal identifier for each category. Then store the category display name in a hashmap just like you store products. This indirection is useful - because it lets you store additional information for a category. For example, if you later decide to display "Most Popular Product" for each category, such a schema would be useful.
Storing Products in Category
You can create a key like category:books:products
and then store the ids for each product. This can be a list, a set or sortedset - depending on what you want to do with the data.
Using a Set
or SortedSet
lets you perform intersections. These come in handy when you want a subset of items, such as 'Books published by O'Reilly". To do this, you will have to maintain another set "publisher:preilly" that contains book ids.
Storing a collection of Categories
Now, you suggested a SortedSet
, which is one possible solution. But you can also use a list if the order of categories isn't going to change dynamically. For example, if you always want to display categories in ascending order, a list is good enough.
A SortedSet proves useful if the order will change dynamically. For example, if you want to display categories on the basis of the number of products in each category - then storing them in a SortedSet is a good idea.
Also, remember, you can use several lists or sortedsets - each collection can represent a different use case. Lets assume you don't want to sell books to overseas customers. In that case, you can have another key categories:overseas
and store the categories you want to display.