2012-08-16 52 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