在Redis中存储2d数组的最佳方法是什么?

时间:2016-01-20 14:02:27

标签: node.js database redis

我想存储如下所示的数据:

{ 
  20160120: [
    ["slug", "title", "date"],
    ["slug", "title", "date"],
    ["slug", "title", "date"]
  ]
}

在Redis中执行此操作的最佳方法是什么?

3 个答案:

答案 0 :(得分:3)

每当你想到Redis中的一些复杂结构时,你应该考虑正确的分解。

带有LIST的条目数据

如果您的数据具有常规结构(如python中的named tuple) - 使用LIST进行存储(more about this):

LPUSH entry:20160120:0 slug title date
LPUSH entry:20160120:1 slug title date
LPUSH entry:20160120:2 slug title date

这会给你

  1. 最节省RAM的方式来存储数据。
  2. 最快的迭代速度。
  3. 如果您的数据有非常规结构 - 您可以使用@ h0x91B答案中的HASH。

    第一维?

    是的,您可以将ZSET用作@ h0x91B建议,但如果您没有计划从第一个维度中删除条目,则可以使用普通增量键来保留最大索引 - INCE ARRAY:20160120 1。像max count模式一样使用它,因为在大多数情况下,您可以直接读取第二维数据,而无需实际检查此数据是否存在。

    例如对于LIST案例(LUA代码,KEYS是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 ;
    

    ZSET方式?

    这种方式是一些硬核,但允许您在一个查询中存储和获取数据,并将所有数据保存在一个有序集中。此外,如果您有数百万个条目(Redis can be a problem中的简单键过多),则可能会节省更多RAM。所以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     
    

    查询,例如索引2和20160120日期的所有数据:

    ZRANGEBYLEX entry[20160120: + 
    

答案 1 :(得分:1)

如果您需要在数组中保存订单,可以使用许多ZSET,如果订单无关紧要,请使用SET。

如果SET对于SMEMBERS来说很大,请使用SSCAN迭代整个列表。

您也可以使用HSET并以这种方式存储数组条目:

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

我的观点 - 用于存储订单的HSET + ZSET是最佳方式(在内存中的密钥将被优化,因此不需要额外的内存)

答案 2 :(得分:1)

有时候合适的替代方法是将序列化数组存储为String(或者如果存在多个这样的数组,则可能作为另一个数据结构中的成员)。请记住,MessagePack和JSON都具有Redis内置的支持功能。 Lua,所以你可以很容易地利用它进行有针对性的读取和写入。

当然,折衷是de / serializng所需的计算资源。