2011-08-18 32 views
0

Heres的东西我正在考虑做的事情,我想知道你是否认为这是一个好主意。Groovy:MultiValueMap与地图作为键

我找回了一堆行从数据库,这在常规给我列出的清单是这样的:

[ 
    [ 'Dog', 'M', 'Mutt', 'Sammy' ], 
    [ 'Cat', 'F', 'Siamese', 'Pat' ], 
    [ 'Dog', 'M', 'Husky', 'Taco' ], 
    ... 
] 

未设置我的真实数据,但你的想法。

因为我会很频繁地提取这些数据,并在将其呈现在UI中之前对其进行一些分析,所以我想将其存储在由groovy映射(即LinkedHashMaps)为关键字的MultiValueMap中,以便我可以检索这些位我需要的部分,而不是每次都去DB。它是来自多个表格的数据子集的缓存(比上面的动物数据更复杂)。

我将能够使用它像这样:

animals.get([species:'Dog', gender:'M']) 

回报:

[['Sammy', 'Mutt'], ['Taco', 'Husky'] ] 

我觉得我有一些想法如何实现它,所以我没有真正寻找一个(虽然如果你有一个新的建议,请分享)。我主要是在寻找某人告诉我这种情况不会出于某种原因起作用,或者听起来不错,或者它不会扩展等。或者也许有一些更简单的方法来获得类似的功能。还有一点需要考虑:整个数据集有时可能很大,例如,几十万条记录。如果不是这样,除了每次击中数据库之外,处理它的最好方法是什么?我知道有很多关键/值缓存解决方案,但我不认为我需要为我所做的工作承担任何重任。它只是一个使用率很低的小型Web应用程序,大部分是我正在为其构建的公司的内部应用程序。

回答

2

如果您使用的值的子集是静态/确定性的,我只需将其转换为字符串并将其用作映射中的键。所以,而不是animals.get([species:'Dog', gender:'M']),我会用animals.get('species:Dog:gender:M')

我知道你说你认为一个键值存储过于重量级,但这也是Redis的完美用例,它可以是natively store things like hash maps

你谈论的存储缓存的种类正是我们如何在我工作的生产环境中使用它,而且它非常棒。它非常快速,并且使其可用于所有正在运行的进程,而不必拥有单个或多个大型地图的副本。缓存失效也是你需要考虑的一点,redis有助于解决这个问题。

您可以使用grails-redis plugin来记忆您的数据库调用,以便它首先自动检查redis是否在缓存中,如果不在缓存中,它将查询数据库并在返回之前将其粘贴到缓存中。有关更多详细信息/示例,请参阅docs on github

return redisService.memoizeHash('species:Dog:gender:M') { 
    // database call that returns object, then you turn that into hash 
    Dog d = Dog.findBy... 
    [species: d.species, gender: d.gender, breed: d.breed, name: d.name, ...] 
} 

这种方式,仅查询,如果Redis的已经没有它在高速缓存中的数据库。在缓存未命中时,它将返回值保存在指定密钥的redis中。

(免责声明,我是grails-redis plugin的作者,所以我有一些偏见)

0

使用可变Map作为关键字是一个非常糟糕的主意,因为如果关键字发生变化,它将不会被发现。