[Web] 메인 화면, N:M 연관관계

업데이트:



시작하며


‘개발자 행사를 알려주는 프로젝트’서버 개발을 하고 있는데요.

기술적으로 고민한 내용 중에 공유하고 싶은 내용이 있어 글을 적게 되었습니다.

그 주제는 바로,

‘트래픽이 많은 페이지에서 다대다(N:M) 연관 관계의 데이터를 어떻게 효율적으로 다룰 것인가’ 입니다.



고민의 시작


어떻게 고민이 시작되었는지 설명드리겠습니다.

먼저, 해당 서비스는 메인 페이지에서 ‘개발자 행사들’ 을 확인할 수 있게 해주는데요.

쉽게 카드 형식으로 행사를 리스트업 한다고 하겠습니다.


image

"이해를 돕기 위해 즉석으로 만들어본 것으로, 실제 웹 페이지와는 무관합니다. ✋"



이것은 1차 개발인데요.

위의 API가 개발되면, 각 행사에 ‘태그’를 붙이도록 추가 개발이 진행됩니다.

가령, 예시의 'MongoDB Atlas 웨비나 시리즈'는 ‘클라우드’ 와 ‘온라인’ 이라는 태그가 달리게 됩니다.


행사는 여러 태그를 가질 수 있고, 태그 역시 여러 행사를 가질 수 있으니

행사와 태그 사이의 관계는 N:M 연관 관계가 됩니다.

태그까지 추가 개발된 화면이 다음과 같다고 가정해보겠습니다.


image



이렇게 되면, RDB에서는 다대다 관계를 테이블 2개로 나타낼 수 없으니,

연결 테이블을 추가해야 할 것입니다.

간단하게 ERD를 그려본다면 다음과 같겠죠?


image



그런데,,,!!

메인 페이지에서 개발자 행사들을 보여주려면, 2번의 Join이 발생하게 됩니다.

가장 트래픽이 많이 발생할 페이지에서 이런 Join 비용이 발생한다는 것이 고민이 되었습니다.

대안으로 생각해낸 방법이 태그를 ',' 로 구분해서 하나의 String으로 가지려고 했습니다.

비록 프론트에서 한 번 더 데이터 작업을 해줘야 하겠지만, Join 비용보다는 나은 방법이라고 생각했습니다.

image


하지만 결정적으로, 아래처럼 태그로 행사를 분류를 하려면,

반드시 Tag 테이블이 필요했습니다.

image

어떻게 해야할까,,, 고민한 끝에!



코드 결론 - JPA편


(사실 이게 정답이라고 자신있게 말하지는 못하지만,) 저희 서버 팀이 내린 결론은!

1) DevEvent에 String으로 여러 tag들을 가지도록 구현

2) DevEvent와 Tag 사이 연관 관계 태이블을 추가

2가지 모두 사용하는 방법으로 결정했습니다.


이렇게 하게 되면, 트래픽이 많이 발생하는 페이지에서의 Join 비용을 줄이면서,

태그로 분류하는 기능까지 가져갈 수 있습니다.

왜냐하면, 메인 페이지에서 행사 전체를 보여줄 때는 DevEvent 테이블의 tags 컬럼을 사용하여 Join을 줄이고, 태그로 행사를 분류할 때는 연관 관계 테이블을 이용하면 되기 때문입니다.

image


아직 JPA에 대해서 빙산의 일각 밖에 모르지만, 이번 기회를 통해서 공부한 바가 큽니다.

  • 다대다 연관 관계의 경우, 연결 테이블을 @Entity로 만들고, @ManyToOne와 @OneToMany로 해결하자.

    => 이유는 @ManyToMany로는 연결 테이블에 컬럼을 추가하거나 하는 커스터마이징이 불가능하기 때문입니다.

  • 일대다 인 경우, ‘다’ 쪽이 FK를 가진다.

    => ‘일’ 인 쪽에서 FK를 가지면, 하나의 테이블 변경 시 양쪽 두 테이블 모두 변경해야하는 상황이 발생합니다.

  • FK를 가진 쪽이 연관 관계의 주인이다.



Tips


마지막으로 어노테이션이 헷갈리시는 분을 위한 팁을 드리고 글을 마치겠습니다!! 🚀🚀🚀

image

  • @ManyToOne 은 변수가 한 개이고,
  • @OneToMany 는 변수가 여러 개입니다.



이번 글은 적으면서도 너무 재밌었고, 제 자신에게도 도움이 많이 되었습니다.!!!

오늘도 수고하셨습니다~~~ 😊




카테고리:

업데이트: