【问题标题】:Which datatype to use for this RedisCache implementation?此 RedisCache 实现使用哪种数据类型?
【发布时间】:2019-12-03 01:09:36
【问题描述】:

我有以下数据库表结构:

Id(string)  Type(string)  BeginDate(datetime) CloseDate(dateime) Source(string)
"+ww100"     "L"           23-JAN-20               23-APRIL-20     XYZ
"+ww100"     "L"           23-JAN-20               23-APRIL-20     XYZ
 ---         ---              ---                      ---         --- 

您可能已经观察到,此表没有任何主键,这意味着可能存在重复数据。现在我需要将此表数据存储在 Redis 缓存中并随后检索它。 示例:我可能想根据Id进行搜索,即使有多个记录,我也想全部检索并进行处理。 由于我是 Redis 的新手,您能否建议我在此用例中使用哪种数据类型?由于键不是唯一的,我认为不可能存储为字典类型的数据结构! 提前致谢。

【问题讨论】:

    标签: c# redis stackexchange.redis


    【解决方案1】:

    由于您对检索或修改记录中的字段不感兴趣,但大多数时候检索整个记录,您可以将其序列化为您喜欢的格式,如 JSON 或简单地:

    +ww100|L|23-JAN-20|23-APRIL-20|XYZ
    

    | 或您喜欢的分隔符分隔,确保您的分隔符不会成为数据字段的一部分或相应地转义。

    使用排序集

    由于没有什么可以区分两条相同的记录,因此您可以简单地保留一个计数器。

    假设你正在存储:

    Id(string)  Type(string)  BeginDate(datetime) CloseDate(dateime) Source(string)
    "+ww100"     "L"           23-JAN-20               23-APRIL-20     XYZ
    "+ww100"     "L"           23-JAN-20               23-APRIL-20     XYZ
    "+ww101"     "E"           24-JAN-20               24-APRIL-20     ABC 
    

    您使用ZADD 插入,使用INCR 选项。如果是新的,它将插入。如果是重复的,就会增加计数。

    > ZADD myData INCR 1 +ww100|L|23-JAN-20|23-APRIL-20|XYZ
    "1"
    > ZADD myData INCR 1 +ww100|L|23-JAN-20|23-APRIL-20|XYZ
    "2"
    > ZADD myData INCR 1 +ww101|E|24-JAN-20|24-APRIL-20|ABC
    "1"
    > ZRANGEBYSCORE myData -inf +inf WITHSCORES
    1) "+ww101|E|24-JAN-20|24-APRIL-20|ABC"
    2) "1"
    3) "+ww100|L|23-JAN-20|23-APRIL-20|XYZ"
    4) "2"
    

    注意重复记录如何出现一次,但有计数。

    然后您可以使用ZSCAN 查询给定的 ID 以获取与 ID 匹配的所有记录:

    > ZSCAN myData 0 MATCH "+ww100|*"
    1) "0"
    2) 1) "+ww100|L|23-JAN-20|23-APRIL-20|XYZ"
       2) "2"
    

    ZSCAN 的缺点是您可能需要多次调用,直到光标回到零,并且您正在遍历服务器端的所有记录。

    对每个 ID 使用排序列表

    如果您希望每个 ID 都具有最佳查询性能,那么每个 ID 使用一个排序集。

    保留一个包含所有 ID 的集合。

    要存储,然后你先使用SADD添加/确保ID:

    > SADD myDataIDs +ww100
    (integer) 1
    > ZADD myData:+ww100 INCR 1 +ww100|L|23-JAN-20|23-APRIL-20|XYZ
    "1"
    

    这里的缺点是要获取所有记录,需要调用SMEMBERS myDataIDs获取所有ID,然后为每个ID调用ZRANGEBYSCORE

    确保在适当的时候使用pipelining 来节省往返时间。

    你可以使用Lua scripts来优化一些操作。这里以获取所有记录为例:

    local keys = redis.call('SMEMBERS', KEYS[1])
    local r = {}
    for i, key in ipairs(keys) do
      r[i] = redis.call('ZRANGEBYSCORE', 'myData:'..key, '-inf', '+inf', 'WITHSCORES')
    end
    return r
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 2010-10-10
      • 1970-01-01
      • 2018-06-11
      • 1970-01-01
      • 2011-07-20
      • 2012-11-07
      相关资源
      最近更新 更多