SQL 조인 대 하위 쿼리: 게임 체인저

여러 테이블이 포함된 SQL 쿼리를 작성할 때 항상 테이블 조인 또는 하위 쿼리 사용에 대한 끊임없는 논쟁이 있습니다.

모든 방법에는 장단점이 있습니다. 나의 자연스러운 선택은 테이블에 합류하는 것입니다. 유지 관리 및 읽기가 더 쉽다는 것을 알았습니다. 그러나 조인보다 하위 쿼리를 확실히 선호하는 사용 사례가 하나 있습니다.

두 개의 데이터 모델, 게시물 및 댓글이 있는 블로그 시스템을 구축한다고 가정해 보겠습니다. 둘 사이의 관계는 일대다입니다. 모든 게시물에는 많은 댓글이 있을 수 있습니다.

이제 상위 3개의 최신 댓글과 함께 상위 10개의 최신 게시물을 반환하는 엔드포인트를 구축하려고 합니다.
머리에 떠오를 수 있는 첫 번째 아이디어는 상위 10개 게시물을 먼저 쿼리한 다음 댓글을 쿼리할 수 있다는 것입니다. 또한 두 테이블을 결합하여 30개의 행을 생성하고 백엔드에서 그룹화하는 것을 고려할 수 있습니다.

필요한 애플리케이션 코드 없이 관련 게시물과 댓글을 반환하는 쿼리를 만들 수 있다고 말하면 어떻게 될까요?



최근에 저는 Postgres JSON 기능의 놀라운 기능을 발견했습니다! JSON 함수를 사용하면 이 작업을 쉽게 수행할 수 있습니다. MongoDB를 사용하고 있는 것처럼 느끼게 하는 쿼리를 만들 수 있습니다.

실제로 보자!

select id, title, (
    select coalesce(jsonb_agg(res), '[]'::jsonb) 
        from (select id, content from comment 
            where comment."postId" = post.id 
            order by "createdAt" desc limit 3) as res
) as comments
from post
order by "createdAt" desc
limit 10;


숨을 쉬고, 긴장을 풀고, 잠시 시간을내어 가라 앉히고 여기서 무엇을했는지 봅시다 ...

기본 SQL 이해가 있다고 가정하므로 일반적인 스키마를 이해하고 있을 것입니다. 복잡한 부분을 살펴보겠습니다.

(
    select coalesce(jsonb_agg(res), '[]'::jsonb) 
        from (select id, content from comment 
            where comment."postId" = post.id 
            order by "createdAt" desc limit 3) as res
) as comments


여기에서 하위 쿼리에 하위 쿼리를 만듭니다. 내부 선택은 기본 쿼리의 모든 게시물에 대한 최신 3개 댓글을 저장하는 결과 집합을 만듭니다.

select id, content from comment 
            where comment."postId" = post.id 
            order by "createdAt" desc limit 3


이것은 post 테이블을 참조하는 where 절을 추가하여 달성됩니다. 지금까지 기본 하위 쿼리 항목입니다.

이제 멋진 부분jsonb_agg이 있습니다. jsonb_aggcount와 마찬가지로 집계 함수입니다. 집계 함수는 N 행의 결과 집합을 단일 값으로 변환합니다. 우리의 경우 jsonb_agg는 N 행을 실제 JSON 배열로 바꿉니다! jsonb의 b는 이진수를 나타냅니다. 응답 크기를 최적화하기 위해 결과를 이진 데이터로 인코딩합니다. 데이터베이스 드라이버는 일반 JSON 개체로 다시 디코딩하는 것을 알고 있으므로 걱정하지 마십시오.
jsonb_agg 를 사용하여 최신 댓글 3개가 포함된 모든 게시물에 대해 JSON 배열을 동적으로 생성합니다.

마지막 부분은 coalesce 이며 게시물에 댓글이 전혀 없는 경우 빈 배열이 반환되도록 합니다.

위와 같이 복잡한 쿼리를 반환하는 쿼리를 생성해야 할 때마다 항상 하위 쿼리와 화려한jsonb_agg 를 사용합니다. 이것은 GraphQL 서버를 구축할 때 매우 일반적입니다. N+1 문제를 해결하는 좋은 방법입니다.

당신은 여기까지 살아남았고 당신이 자랑스럽습니다! 다음 SQL 쿼리를 위한 새로운 기능 세트를 잠금 해제했으면 좋겠습니다.


daily.dev은 새 탭마다 최고의 프로그래밍 뉴스를 제공합니다. 우리는 당신이 미래를 해킹할 수 있도록 당신을 위해 수백 개의 검증된 소스의 순위를 매길 것입니다.

좋은 웹페이지 즐겨찾기