본문 바로가기

JPA/상속관계 매핑

슈퍼타입 서브타입 논리 모델 구현 전략

객체의 상속과 DB의 슈퍼타입 서브타입

객체에는 상속이라는 개념이 존재한다.
하지만 관계형 DB에는 상속이라는 개념이 존재하지 않는다.
대신 슈퍼타입, 서브타입 관계라는 상속과는 다르지만 유사한 개념이 존재한다.
상속관계 매핑이란 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑해주는 것이다.

 

DB 논리모델

위 그림은 슈퍼타입, 서브타입 관계를 표현한 DB 논리모델이다.(수기로 작성해서 삐뚤빼뚤이지만 그래도 ㅠㅠ...)
(현재 논리 모델에서 슈퍼타입은 가전제품이고, 나머지 아래쪽에 기구들은 서브타입이 된다.)
이 슈퍼타입 서브타입 논리 모델을 물리 모델(실제 테이블)로 구현하는 방법은 크게 3가지가 있다.

이번 시간에는 구현 방법 3가지에 대해 알아보겠다.

슈퍼타입 서브타입 논리모델 → 물리모델 변환 전략 3가지

1. 조인 전략

조인 전략은 상위 테이블(슈퍼타입의 테이블)을 하위 테이블(서브타입의 테이블)들이 외래키를 사용해 참조하는 방식이다.

DTYPE은 어떤 종류의 가전제품인지 판별하기 위한 열이다.
(조인 전략을 사용하는 경우 해당 열이 없어도 하위테이블과의 조인을 통해서 어떤 상품인지 판별가능하나,
상품의 종류를 알고싶을 때마다 3개의 하위테이블과 JOIN하는 것은 비효율적이기때문에 있는 것이 좋다.)
하위 테이블의 PK는 상위테이블을 참조하기 위한 FK의 역할도 한다.
또한 상위테이블에는 공통컬럼을 두고 서브타입들은 각각 자신만의 컬럼을 가지게 된다.

  •  장점
    • 정규화된 테이블 사용
    • 외래키 참조 무결성 제약조건 활용가능
    • 저장공간 효율화
  • 단점
    • 데이터 조회 시 select join문이 날아가 쿼리가 복잡해지고 성능이 저하된다.
    • 데이터 저장 시 item 테이블과 하위 테이블에 insert 쿼리를 2번 날려야 한다.

가장 정석적인 방법이고, 성능 저하도 그렇게 크지 않기때문에 좋은 방법이다.

 

2. 단일테이블 전략

단일테이블 전략은 슈퍼타입과 서브타입 관계에 있는 엔티티들을 하나로 합쳐 테이블로 구현하는 전략이다.

DTYPE은 해당 제품이 어떤 종류의 가전제품인지 판별하기 위한 열이다.
(단일테이블 전략을 사용할 경우 해당 열은 필수적이다.
DTYPE과 같이 Type 구분을 위한 열이  없다면 정확하게 Type을 구분할 수 없다.)

  •  장점
    • Insert 및 select(join 없이) 쿼리가 한 번에 나감 (성능 상의 이점이 있음)
    • 조회 쿼리가 단순(테이블 하나를 조회하기때문)
  • 단점
    • 서브타입의 엔티티가 매핑한 컬럼들은 모두 null을 허용해야 함
    • 하나의 테이블에 모두 저장하므로 테이블이 커질 수 있고, 상황에 따라 조회 성능이 되려 나빠질 수 있음

3. 구현클래스마다 테이블 전략

서브 타입의 엔티티들을 완전히 독립적인 테이블들로 구현해내는 전략이다.
3개의 테이블이 서로서로 ID가 겹쳐서는 안 된다.
최악의 전략이다. 사용하지 말자!

  •  장점
    • 서브 타입을 명확하게 구분해서 처리 시 효과적
    • Not null 제약조건 사용 가능
  • 단점
    • 하위테이블들을 join해서 쿼리하기 어려움 => 조회 시 성능이 매우 나쁘다
      ex) 1번 id를 가진 가전제품 조회 시 => 3개의 테이블을 모두 join해서 찾아야 한다.
    • 3개의 테이블이 id가 겹치지 않도록 관리해야 한다.
    • 공통 컬럼을 공통으로 사용하지 않아 저장공간이 낭비된다.

전략을 선택할 때 테이블 당 클래스 구현 전략은 배제하고 조인전략과 단일테이블 전략 중 선택하는 것이 좋다.
확장될 가능성이 적고, 데이터가 많이 쌓이지 않는다면 단일테이블 전략을 사용하는 것이 좋고,
확장될 가능성이 있고, 데이터가 많이 쌓인다면 조인전략을 사용하는 것이 좋다.

 

참고강의: 배달의 민족 개발팀장 김영한 강사님의 JPA 강의

 

'JPA > 상속관계 매핑' 카테고리의 다른 글

상속관계 매핑 코드 실습  (0) 2021.08.18
상속관계 매핑  (0) 2021.08.18