2012-08-16 81 views
0

我正在使用Spring和Hibernate編寫一個Web應用程序,它將人,組,帖子,附件,註釋等相當複雜的領域模型映射到mysql數據庫中。這個問題源自嘗試優化查詢的評論,但也適用於網站的其他方面。將派生數據存儲在規範化關係數據庫中的策略

爲了簡化這個問題,評論與帖子有很多:1的關係,與帖子的關係很多:1。每個組都有一個基礎網址({/ group_slug}),每個帖子都可以通過該網址後接斜線和帖子ID(/ {group_slug}/{post_slug})來訪問。這些帖子有一個引用他們的父母,並計算他們的網址在一個瞬態的方法,要求父母的網址,並追加它的塞子到它的末尾。如果評論需要它的url,它會詢問它的父母(帖子),然後查詢該組並創建url。它工作正常,除了以下性能問題:

在主頁上,我想顯示來自每個用戶組的最近評論在單個列表中的所有最新評論。在每條評論下方都應該鏈接到評論所寫的帖子。這很重要,這是一個相對較快的查詢,但對於目前的模型,我無法弄清楚如何有效地做到這一點。我現在的Hibernate查詢(JPQL)看起來像這樣,每個組的用戶中的一員:

select c from Comment c where c.target.group.id = :groupId and c.dateCreated > :date 

但隨後獲得對目標項目的每個URL(由於休眠急切地加載一個:很多關係從評論到目標,然後是目標到組),目標和組也必須從數據庫中加載,對於每個評論。

有沒有更好的方法來組織這個查詢,或重新設計域模型,以便我不必每次都加載太多的數據?如果不是,每次創建新評論時,對數據庫進行反規範化並將評論父級的URL與其存儲在數據庫中有什麼不利之處?這些實體沒有經常更換網頁,但是可能會改變帖子的內容。我可以通過循環瀏覽所有關於任何slu change變化和更新網址的相關評論來處理這種情況,但它似乎仍然不符合最佳實踐。

+0

在您的域對象生成一個URL似乎並不喜歡我的最佳實踐。我不知道你使用的是什麼前端,但是生成url應該在那裏發生。 – siebz0r 2012-08-17 11:43:36

回答

0

你可以貪婪加載它在查詢阻止SELECT N + 1的發生

select c from Comment c join fetch c.target t join fetch t.group g where g.id = :groupId and c.dateCreated > :date