uju's Tech

[Node.js : Sequelize] join 이 2번 필요할 때 본문

Node

[Node.js : Sequelize] join 이 2번 필요할 때

ujusy 2021. 5. 28. 23:14

<본 포스팅은 공부 목적으로 작성되었습니다. 혹시 틀린 부분이 있거나 문제가 되는 부분이 있다면 답글 달아주세요!>

 

개발을 진행하면서 가끔 3개의 테이블을 조인하여 가져오는 경우가 발생한다.

또 ORM 을 쓸 때 간혹 join 할 수 있는 테이블을 각각 선택하여 가져오는 경우가 있는데 이럴 경우 n+1 Problem 이 발생한다.

 


N+1 Problem이란?

 

스스로 이해한 것을 정리해보면 유저 테이블과 유저 테이블과 연결된 할 일 테이블이 있을 때 , 할 일 테이블의 리스트를 쭉 가져오는 쿼리 1번

해당 쿼리에서 가져온 데이터 N개 만큼 또 일치하는 사용자를 찾는 쿼리 N번.

그래서 N+1 문제가 발생한다고 이해했다.

 

이를 방지하려면 join를 적절히 이용해줘야 할 것 같다.

 

아래 링크를 확인해 보면 될 것 같다.

https://zetawiki.com/wiki/N%2B1_%EC%BF%BC%EB%A6%AC_%EB%AC%B8%EC%A0%9C

 

N+1 쿼리 문제 - 제타위키

다음 문자열 포함...

zetawiki.com


서론이 길었고.. sequelize에서 테이블 2개 join 하는 것과 테이블 3개를 join 하는 것을 알아보도록 하겠다.ㅎㅎ

 

 

1. join 2 tables

할 일 목록을 가져오면서 해당할 일 목록의 유저 정보도 포함해서 가져온다.

const toDo;
const attributes = ['id', 'title']
toDo = await ToDO.findAll({
	attributes,
    include: [{
        model: User,
    }],
});

 

2. join 3 tables

할 일에 연결된 유저와 유저에 연결된 테스트 테이블을 모두 조인한다.

- A - B - C 이렇게 연결된 테이블에서 A를 기준으로 가져올 때

const toDo;
const attributes = ['id', 'title']
toDo = await ToDO.findAll({
    attributes,
    include: [{
        model: User,
        include: [{
          model: Test,
        }],
    }],
});

 

계속 include 해주면 된다.. 아주 간단하다 ㅎㅎ 

 

 만약에    유저 리스트를 조회하는데 할 일 , 테스트 테이블에 대한 정보를 조인하고 싶으면 아래와 같이 해주면 된다. 

 

- A - B - C 이렇게 연결된 테이블에서 B를 기준으로 가져올 때

User.findAll({
    attributes,
    include: [{
        model: Todo,
    },{
        model: Test,
    }],
});

 

구조는 간단하다. @~@ N+1 Problem를 주의하여 Join을 잘 이용해 보고 코드의 효율성? 에 대해서도 많이 생각해 보아야겠다.. ㅜㅜ

Comments