DB/JPA

[JPA] 상속관계 매핑

꾸준함. 2021. 9. 7. 00:37

개요

객체에는 상속이라는 개념이 있지만 관계형 데이터베이스에는 상속관계가 없습니다.

객체지향 언어인 Java를 사용하는 프레임워크에서 JPA를 적용하기 위해서는 객체 상속과 유사한 구조를 구현해야 하는데 마침 RDBMS는 객체 상속과 유사한 모델링 기법인 슈퍼타입/서브타입 구조를 제공합니다.

따라서, 이번 게시글에서는 객체의 상속, 구조와 DB의 슈퍼타입/서브타입 관계를 매핑하는 상속관계 매핑에 대해 알아보겠습니다.

 

1. 상속관계 매핑

상속관계 매핑은 슈퍼타입/서브타입 논리 모델을 실제 물리 모델로 구현하는 방법이며 아래와 같이 크게 3가지가 있습니다.

  • 조인 전략 (JOINED)
  • 싱글 테이블 전략 (SINGLE_TABLE)
  • 구현 클래스마다 테이블 전략 (TABLE_PER_CLASS)

 

상속관계 매핑 관련된 주요 어노테이션으로는 아래와 같이 크게 3가지가 있습니다.

  • @Inheritance(strategy = InheritanceType.OOO)
    • 앞서 언급한 전략들 중 하나를 선택하는 어노테이션
    • JOINED, SINGLE_TABLE, TABLE_PER_CLASS 중 하나 선택
    • 명시 안할 경우 SINGLE_TABLE이 디폴트로 선택이 됨
  • @DiscriminatorColumn(name = OOO)
    • JOINED 전략의 경우 SINGLE_TABLE과 달리 각 객체마다 테이블이 생성됨
    • 따라서 서브 클래스를 삽입할 때 슈퍼 클래스 테이블에도 삽입이 되는데 이때 어떤 서브 클래스의 Entity인지 표현하는 것이 운영적인 측면에서 좋음
    • 따라서, @DiscriminatorColumn 어노테이션은 슈퍼클래스에서 선언
    • 서브 클래스 엔티티를 명시하는 컬럼은 디폴트로 DTYPE이며 name 속성에 별도 컬럼명을 명시해줄 수 있음
    • SINGLE_TABLE 전략 같은 경우 단일 테이블이므로 DTYPE 칼럼이 무조건 생김
  • @DiscriminatorValue("OOO")
    • @DiscriminatorColumn과 달리 서브클래스에 명시하는 어노테이션
    • 슈퍼클래스의 @DiscriminatorColumn 칼럼 내 어떻게 저장할지 지정하는 어노테이션
    • 디폴트는 객체명 그대로 삽입되며 별도로 명시할 경우 지정한 명칭대로 DTYPE 칼럼에 삽입됨

 

2. 조인 전략 (JOINED)

  • 비즈니스적으로 중요하고 복잡할 경우 사용되는 테이블 전략이며 이상적으로 데이터를 관리할 수 있는 전략
  • 장점
    • 객체마다 테이블이 생성되므로 테이블 정규화가 잘 되어 있음
    • 객체마다 테이블이 생성되므로 외래 키 참조 무결성 제약조건 활용 가능
    • 저장공간이 분리되어있으므로 저장 공간을 효율적으로 활용 가능
  • 단점
    • 조회 시 Join을 너무 많이 할 경우 성능 저하 우려 (반정규화를 해야 할 수도 있음)
    • 기본적으로 Join문을 쓰기 때문에 단일 테이블 전략에 비해 조회 쿼리가 복잡
    • 데이터를 삽입할 때도 삽입 SQL을 2번 호출 (네트워크를 여러번 탐)

 

Superclass - Vehicle, Subclass - Car, Truck

 

 

 

Join을 통해 조회

 

 

 

3. 싱글테이블 전략 (SINGLE_TABLE)

  • 테이블들을 분리하지 않고 하나의 테이블에 모든 칼럼을 저장하는 전략
  • 장점
    • 조인이 필요 없기 때문에 일반적으로 조회 성능이 더 빠름
    • 조회 쿼리가 비교적 단순함
    • JOINED 전략과 달리 INSERT문도 한 번만 실행
  • 단점
    • 자식 Entity가 매핑한 칼럼에 대해서는 모두 NULL 허용해줘야 함
    • 단일 테이블에 모든 것을 저장하기 때문에 테이블 크기가 커질 경우 조회 성능이 오히려 느려질 수 있음
      • 위와 같은 경우, 조회 조건에 맞는 테이블 파티셔닝을 진행할 경우 해결할 수 있는 문제
      • 조회를 자주 하는 페이지일 경우 단일 테이블에 대해 테이블 파티셔닝을 진행한 후 조회하는 것이 JOINED 전략보다 유리할 수 있음

 

Superclass - Vehicle, Subclass - Car, Truck

 

 

* JPA의 장점: JOINED 전략에서 SINGLE_TABLE 전략으로 전환하더라도 코드 변화가 거의 없음 (테이블 Entity 전략만 변경해주면 됨)

* 따라서, 삽입, 조회하는 코드는 JOINED 전략과 완전 동일

 

4. 구현 클래스마다 테이블 전략 (TABLE_PER_CLASS)

  • JPA에서 지원을 하지만 결론부터 말하자면 사용하면 안 되는 전략
  • 해당 전략은 슈퍼 클래스의 테이블은 생성되지 않으며 서브 클래스의 테이블들만 생성이 됨
  • 서브 클래스 테이블들끼리 연결을 지을 수 있는 칼럼이 없기 때문에 조회 쿼리를 작성하기 어려우며 여러 자식 테이블을 함께 조회할 때 성능이 느린 UNION SQL을 통해 조회를 해야 함
  • 따라서, DBA와 개발자 간 trade off를 고려한 뒤, JOINED 전략을 선택할 것인지, SINGLE_TABLE 전략을 선택할 것인지 정하는 것을 추천

 

Superclass - Vehicle, Subclass - Car, Truck

 

 

UNION SQL을 통한 조회


 

정리

  • 정리를 하자면, 세 가지의 테이블 전략 중 사용할 수 있는 전략은 JOINED와 SINGLE_TABLE 뿐
  • 관리하기 편한 방식은 SINGLE_TABLE 전략이며 조회를 자주 할 경우 효율적
  • 비즈니스적으로 중요하고 복잡할 경우 JOINED 전략을 추천

 

출처

자바 ORM 표준 JPA 프로그래밍 - 기본편 (김영한 강사님)

반응형

'DB > JPA' 카테고리의 다른 글

[JPA] 프록시와 연관관계 관리 정리  (0) 2021.09.14
[JPA] @MappedSuperclass  (0) 2021.09.07
[JPA] 다양한 연관관계 매핑  (0) 2021.08.31
[JPA] 연관관계 매핑 간단 정리  (0) 2021.08.28
[JPA] Entity 매핑 정리  (0) 2021.08.23