개발 학습일지(TIL)

TIL : typeORM 외래키 없이 조인. getRawMany() vs getMany()

Veams 2023. 3. 27.

nestjs, typeorm mysql 사용환경

 

문제: 엔티티간 관계설정 없이 다른 엔티티의 컬럼 값 가져오기...

작업배경

게시글 내용이 기존에는 33 으로 단순하게 보여주고 있었다.

 

히지만 아무래도 유저들이 사용할 때는 화면에 표기되는 정보의 액션이 많아야 재미있을테니,

위 사진처럼 33 이외에 모임의 참가자, 대기자 명단을 불러오는 작업을 하려 한 것이다.

그래서 참가자, 대기자 명단을 추가하기 위해 쿼리를 새로 작성해야했다.

 

 

시도1

이 작업은 클럽 멤버스 엔티티를 기반으로한 리포지토리에서 값을 불러오면 된다.

참가자, 대기자를 단순하게 불러오는 것은 어렵지 않으나, 

닉네임 정보는 user 라는 다른 테이블에서 조인해서 불러와야했다.

 

사실 엔티티간 관계설정을 했으면 별 고민없이

user 엔티티를 leftjoin(), getMany() 으로 쿼리작성해서 받아오면 됐다.

 

그런데 제약 조건이 생겼다.

팀 협업에서 관계설정을 추가하면 기존 쿼리들을 새로 작성해야한다고....

새로 관계설정 하면 코드가 바뀔 수 있다고 관계설정 하지 말아달라고 해서...

쿼리를 바꾸어 짤 수밖에 없었다. 

 

즉, 현재 클럽 멤버스 엔티티와 유저정보 엔티티 관계설정이 안 되어있었다.

 

시도2

관계설정을 하지 않았기에 getMany() 대신 

getRawMany() 로 받아왔다.

getRaw로 받아오는 덕분에 정보가 좀 달라져서, 날짜를 관리하는 함수도 새로 추가했다.

(이번에 innerJoin과 leftJoin은 별 상관없다.)

 

 

닉네임 값이 함께 불러와지고 있다.

 

 

 

알게 된 점 :

1. getRawMany()와 getMany()의 차이.

현재의 쿼리문에서는 User 엔티티와 조인을 하지 않았기 때문에 getMany() 메서드를 사용해도 값이 불러와지지 않았던 것이다.

 

1) getRawMany() 메서드는 반환값을 엔티티 객체가 아닌 순수한 JSON 데이터로 반환한다.

이 경우, ClubMember 엔티티와 User 엔티티의 조인 없이, User 엔티티의 nickName 컬럼만 가져와서 사용할 수 있게 된 것이다.

 

2) 반면에 getRawMany()대신 getMany()를 사용하면,

반환값이 ClubMember 엔티티 객체이기 때문에 User 엔티티와의 조인이 필요하다!

 

getMany() 메서드는 ClubMember 엔티티 객체를 반환한다.

이 때 ClubMember 엔티티와 User 엔티티를 조인하면서, User 엔티티의 nickName 컬럼도 함께 가져와야 한다.

그래서 User 엔티티와 관계 설정을 해놓은 상태에서 조인을 하는 처리가 필요했다.

 

2. 외래키 없는 join은 사실 권장되는 방식은 아니다.

외래키는 참조 무결성을 유지하기 위해 사용하는데, 외래키 없이 join을 해와서 쿼리를 사용하면 무결성을 희생시키는 것이 된다. 또한 코드의 가독성도 좋지 못하다. 

 

엔티티간 관계설정이 늘수록 서버실행시 무결성 체크를 위해 서버 속도가 느려질 수 있다는 의견이 있는데, 실제로 우리 팀에서는 프로젝트 중후반부에 서버가 느려진 문제가 발생해서, 튜터님의 제안으로 작업 초기에 구성했던 엔티티간 관계 설정을 재검토하고 최소화하려면서 코드를 바꾼 경험이 있다.

 

마감 압박이 있는 와중에 기존에 작성된 코드(일종의 레거시)를 변경하는 것에 대한 두려움은 증폭됐고 기존 코드의 변경을 최소화해야하는 압력에서 이런 새로운 학습의 기회가 생긴셈이었다.

 

 

https://co1nam.tistory.com/44

 

외래키를 사용하지 않는 이유 feat. 인덱스

외래 키(foreign key) 란 관계형 데이터베이스에서 다른 릴레이션(테이블)을 참조할 때 사용하는 키입니다. 아래 학생 릴레이션을 봅시다. id 학생명 강의명 강의코드 1 개똥이 병충해 방지기법 1231 2

co1nam.tistory.com

 

댓글