假设我有以下课程:
class Demo {
private Integer id;
private Collection<String> tags;
//...
}
然后我有两张桌子:
Demo Tags
id demoId | name
------ -------+-------
1 1 | a
2 1 | b
2 | c
现在我想从数据库中选择所有Demo对象,我可以这样做:
select Demo.id,Tags.name
from Demo
left join Tags on (Demo.id=Tabs.demoId)
然后我可以遍历结果,找到id的演示对象(如果它不存在则创建它)并添加id的标记。
或者我可以使用:
select Demo.id,array_agg(Tags.name)
from Demo
left join Tags on (Demo.id=Tabs.demoId)
group by Demo.id
并且整个事情变得更简单,因为现在我直接将我的id /数组对。这个数组来自JDBC作为一个数组而且......好吧。你明白了。这很容易,尤其比以前描述的方法更容易。
然而由于某种原因,某些事情告诉我这并不完全符合SQL的概念,我怀疑这种方法有一些我想念的缺点。
所以问题是:是否有任何原因(除了可移植性)不使用array_agg&amp;分组来填充对象的集合字段?
答案 0 :(得分:0)
一个原因,主要是:array_agg()
/ group by
将使数据库的工作能够在应用程序中完成,并且添加新的应用服务器通常更容易,也更便宜。
当你对小结果集进行分页时,更有效的方法就是获取:
select Demo.*
from Demo
where …
然后,在另一步骤中:
select Tags.demoId,Tags.name
from Tags
where Tabs.demoId in (…)
这样做允许使用memcached缓存第一个查询结果(如果适用),避免进程中的数据库查询,以及第二个查询中涉及的ID列表以避免进一步的数据库工作,同时允许相对简单的缓存失效。
伪代码:
uncached_ids = []
for demo in demos:
if cached demo.id:
fetch tags for demo.id
else:
uncached_ids[] = id
fetch tags for uncached_ids...