2011-08-18 45 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作爲關鍵字是一個非常糟糕的主意,因爲如果關鍵字發生變化,它將不會被發現。