2014-05-21 6 views
0

내가 다음 클래스가 있다고 가정 : 다음collection을 채우는 데 array_agg를 사용하지 않는 이유가 있습니까?

class Demo { 
    private Integer id; 
    private Collection<String> tags; 
    //... 
} 

와 나는 두 개의 테이블이 있습니다

Demo   Tags 
id   demoId | name 
------  -------+------- 
1    1 | a 
2    1 | b 
       2 | c 

그리고 지금은 DB에서 모든 데모 개체를 선택하려면를, 내가 할 수있는 :

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 

을하고 모든 것은 간단한 많이 가져옵니다

또는 난 그냥 사용할 수 있습니다. 배열은 JDBC에서 배열로 나오고 ... 음. 너는 요점을 가지고있다. 쉽고 특히 이전에 설명한 방법보다 쉽습니다.

그러나 어떤 이유로 나는 이것이 SQL의 개념에 완전히 들어 맞지 않는다는 것을 말해 주며, 나는이 방법이 내가 그리워하는 단점이 있음을 의심 스럽다.

그래서 질문은 : array_agg & 그룹을 사용하여 개체 컬렉션 필드를 채우지 않는 이유는 무엇입니까? 주로

답변

0

한 가지 이유 : array_agg()/group by이 DB를 만들 것입니다 단지뿐만 아니라 응용 프로그램에서 할 수있는 일을하고, 새로운 응용 프로그램 서버를 추가하는 것이 더 쉽고 저렴. 별도의 단계에서, 다음

select Demo.* 
from Demo 
where … 

을 그리고 :

당신이 작은 결과 집합을 paginating 때 그것을 할 수있는 아직 더 효율적인 방법, BTW, 인출하는 것

select Tags.demoId,Tags.name 
from Tags 
where Tabs.demoId in (…) 

이렇게하면 memcached를 사용하여 적용 가능한 경우 첫 번째 쿼리 결과를 캐싱 할 수 있고, 프로세스에서 DB 쿼리를 피할 수 있으며 두 번째 쿼리에 관련된 ID 목록을 사용하여 추가 DB 작업을 피할 수 있으며 상대적으로 간단한 캐시 무효화가 가능합니다.

의사 코드 :

uncached_ids = [] 
for demo in demos: 
    if cached demo.id: 
    fetch tags for demo.id 
    else: 
    uncached_ids[] = id 
fetch tags for uncached_ids... 
관련 문제