Reputation: 3757
I want to store data that looks like this:
{
20160120: [
["slug", "title", "date"],
["slug", "title", "date"],
["slug", "title", "date"]
]
}
What is the best way to do this in Redis?
Upvotes: 1
Views: 1466
Reputation: 6351
Each time you thinking about some complex structure in Redis you should think about right decomposition.
If your data has regular structure (like named tuple in python) - use LIST for storing (more about this):
LPUSH entry:20160120:0 slug title date
LPUSH entry:20160120:1 slug title date
LPUSH entry:20160120:2 slug title date
This gives you
If your data has non regular structire - you HASH as in @h0x91B answer.
Yes, you can use ZSET as @h0x91B suggest, but if you have no plans to delete entries from first dimenstion you can use plain incremental key to keep max index - INCE ARRAY:20160120 1
. Use it like max count
pattern, becouse of in most of cases you can just read you second dimension data without actual check if this data present of not.
For example for LIST case (LUA code, there KEYS is 20160120
):
local maxCount = redis.call("GET", KEYS[1]);
local ret = {};
for i = 0, maxCount, 1 do
table.insert(ret, redis.call("LRANGE", "entry:" .. KEYS[1] .. ":" .. i, 0, -1);
end
return ret ;
This way is somekind of hardcore but allows you to store and get data in one query and keep all data in one sorted set. Also, it may be more RAM saving if you have millions of entries (too much simple keys in Redis can be a problem). So the way of ZRANGEBYLEX:
|- key for your array
| |- index in first dimenstion
| | |-search pattern as first dimenstion key
| | | |-actual value
ZADD entry 0 20160120:slug
ZADD entry 0 20160120:title
ZADD entry 0 20160120:date
And query, for example all data from index 2 and 20160120 date:
ZRANGEBYLEX entry[20160120: +
Upvotes: 3
Reputation: 49942
An alternative approach that is sometimes suitable is to store the serialized array as a String (or perhaps as a member in another data structure if multiple such arrays exist). Keep in mind that both MessagePack and JSON have built-in support in Redis' Lua, so you can easily leverage that for targeted reads & writes.
The trade off, of course, are the compute resources needed for de/serializng.
Upvotes: 1
Reputation: 1246
Many ZSET's if you need save order in Arrays, or use SET's if order not matter.
If SET's is to big for SMEMBERS use SSCAN to iterate over whole list.
Also you can use HSET and store your array entry in this way:
HMSET HSET:ENTRY:20160120:0 "slug" "slug-data1" "title" "title-data" "date" "date-data" HMSET HSET:ENTRY:20160120:1 "slug" "slug-data2" "title" "title-data" "date" "date-data" HMSET HSET:ENTRY:20160120:2 "slug" "slug-data3" "title" "title-data" "date" "date-data" ZADD ENTRY:20160120 0 HSET:ENTRY:20160120:0 1 HSET:ENTRY:20160120:1 2 HSET:ENTRY:20160120:2
My opinion - HSET+ZSET for storing order is best way (in memory keys will be optimised so no extra memory will needed)
Upvotes: 1