(TIL) 20221102, 테이블 연관관계의 역정규화

2022. 11. 3. 01:12TIL(Today I learned)

반응형

🏴󠁩󠁤󠁪󠁷󠁿Facts(한 것) & Findings(배운 것)


인턴을 하면서 배운 것이 몇가지 있는데, RDB상에서 연관관계가 있는 두 테이블을 반드시 매핑하지는 않는다는 것이다.

 

매핑을 하면 어떤 것이 가능할까?

 

한 쪽 테이블에서 반대쪽 테이블의 데이터를 읽을 수 있다.

그리고 생명주기를 같이하기 때문에 JPA의 orphan removal 등의 기능을 이용해서

데이터가 삭제됐을 때 다른 테이블이 데이터도 삭제 할 수 있다.

 

 

그럼 불편한 점은 무엇일까?

 

1. 관리해야할게 많아진다.

생명주기를 같이하는 경우가 많기 때문에 경우를 고려하며 작성한다.

 

2. 특정 필요한 데이터만 가져오고 싶어도,

join을 하는 등 비용이 반드시 발생한다.

 

 

나는 2번째 문제에 대해서 집중했다.

 

책과 책에 대한 리뷰, 그리고 리뷰에 대한 댓글 이렇게 3개의 테이블이 있다고 생각해보자.

 

 

그렇다면 이런 연관관계를 가진 테이블이 만들어질 것이다.

 

 

그럼 책을 클릭하면 책에 대한 리뷰의 갯수를 확인할 수 있는 기능이 있다고 생각해보자.

우리는 RDB를 사용하고 있기 때문에 연관관계를 통해서 조회를 할 수 있다.

 

그럼 자연스럽게 우리는 이런 쿼리를 날리게 될 것이다.

 

select count(r) from Review r left join book on book.reviewid = r.id;

 

그럼 생각해보자.

1.  join 비용 발생

2.  카운트 비용 발생

 

그리고 이런 작업은 책 리스트를 얻고 싶을 때, 즉 화면을 렌더링할 때, 모든 책에 대해서 요청해야할지도 모른다.

그럼 이 비용은 매우 커질 것이다. (물론 페이지별로 요청하겠지만)

 

 

 

그럼 이번에는 연관관계를 사용하지 않고 조회를 하는 방법을 생각해보자.

 

 

우리는 이미 책을 조회할 때, 리뷰의 갯수가 필요하다는 것을 알고 있다.

그렇다면 역정규화를 통해서 책 도메인에 리뷰 갯수를 넣어버리는 것은 어떨까?

 

 

기존의 도메인이 이런 코드였다면,

public class Book {
    private Long id;
    private String title;
    ....
    @ManyToOne
    private Review review;
    
 }

 

아래 처럼 바뀌는 것이다.

public class Book {
    private Long id;
    private String title;
    ....
    private int reviewCount;
    @ManyToOne
    private Review review;

 

이렇게 되면 join비용도 발생하지 않고, 리뷰를 조회하는 비용도 발생하지 않는다.

그냥 Book을 조회할 때 발생하는 조회 비용만이 들 뿐이다.

 

 

이 경우에도 단점은 존재한다.

review가 생성되거나 삭제 될 때, 그 수를 조작해야하기 때문에, 쿼리가 발생한다.

 

 

하지만 리뷰 갯수를 조작하는 횟수보다, 책을 조회하는 횟수가 훨씬 많을 것이고,

그 비용도 더 많이 들 것이기 때문에 이런 방식을 사용하는 것이 비용을 아끼는 방법 중 하나라고 생각된다.

 

 

 

🏴󠁩󠁤󠁪󠁷󠁿Affirmation(자기 선언)


  • 코틀린 || 스프링 || 리액트 강의 듣기 -> 성공
  • 알고리즘 문제 풀기 -> 성공
 
 
반응형