JPA. 상속관계 맵핑

무지성개발자·2024년 2월 15일
0

JPA

목록 보기
6/12

상속관계 맵핑

상속은 객체지향에는 존재하지만 관계형DB에는 존재하지 않는다. 관계형 DB에서 상속관계는 슈퍼타입 - 서브타입를 사용하면 비슷하게 구현 가능하다.

JPA를 이용한 상속관계 맵핑

가령 위와 같은 상속관계를 가진 엔티티가 있다고 생각해보자. 위 관계도는 판매물품의 공통부분은 Item으로 묶고 나머지 속성을 서브클래스로 상속받은 관계도인데 코드는 다음과 같이 작성한다.

# Item Class

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public abstract class Item {
}

# 하위 Class

@Entity
public class Album extends Item{
}

OOP의 상속코드랑 다를게 하나 없다. 여기서 주목해야 할 부분은 @Inheritance@DiscriminatorColumn 두가지다.

@Inheritance

@Inheritance는 상속관계 엔티티를 DB에 어떤 전략으로 표현할지 설정하는 어노테이션 이다. 기본적으로 단일 테이블 전략을 채택하였다.

단일 테이블 전략

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)으로 설정.
사진에 색칠한 컬럼을 보면 Album, Book, Movie 엔티티로 나눠서 관리하는 데이터를 한 테이블에 넣고 필요에 따라 채워서 사용하는 방식이다.

  • 장점
    • 쿼리가 단순
    • 조회 성능이 좋음
  • 단점
    • 하위 엔티티로 관리하는 컬럼에 Null을 허용해야함.
    • 테이블 데이터가 많아지면 오히려 성능 저하가 발생가능.

조인 전략

@Inheritance(strategy = InheritanceType.JOINED)
조인 전략은 슈퍼타입 - 서브타입 관계로 상속관계 비슷한 모양새인데 조인을 사용하여 데이터를 조회하는 방법이다.

  • 장점
    • 정규화 된 테이블
    • 외래 키 참조 무결성 제약조건 활용가능
    • 저장공간 효율화
  • 단점
    • 조인을 사용하여 비교적 조회 쿼리 성능 저하
    • 조회 쿼리 복잡
    • 데이터 저장시 슈퍼 테이블, 서브 테이블 두번 insert발생

구현 클래스 각각 테이블 전략

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
이 전략은 각 하위 엔티티를 각각 테이블로 만들어 사용하는 전략으로 공통된 속성 역시 각각 테이블에서 관리한다. 하지만 데이터지향 관점으로 보나, 객체지향 관점으로 보나 어느 쪽도 추천하지 않는 방식이다.

  • 장점
    • 타입 구분 명확
    • Not Null 제약 사용가능(무결성에 도움이 됨)
  • 단점
    • 자식 테이블을 함께 조회할 때 성능이 느림(UNION 사용)
    • 자식 테이블 통합 조회 쿼리 복잡.

@DiscriminatorColumn

@DiscriminatorColumn 어노테이션은 자식 타입을 명확하게 구분해주는 컬럼인데 단일 테이블 전략, 조인 전략에 보면 DTYPE 컬럼을 만들어 주는 어노테이션이다.

DTYPE 컬럼에 Movie, Book, Album 같이 표현해줌으로 어떤 타입의 데이터인지 편하게 구분하도록 도와주는 것 이다.

@DiscriminatorColumn은 기본 DTYPE 컬럼을 생성하도록 되어있으며 name속성 값으로 컬럼명을 변경할 수 있다. 또한 하위 타입명은 기본적으로 Entity명으로 작성이 되는데 하위 엔티티에 @DiscriminatorValue("컬럼 벨류")를 사용하여 타입값을 변경 할 수 있다.

결론

  • 하위 엔티티를 각각 테이블로 사용하는 것은 지양하는 것을 추천
  • 먼저 조인 전략으로 생각해보고 간단한 데이터 구조 및 적은 데이터 양이 예상된다면 단일 테이블 전략을 사용하는 것을 고려.
profile
no-intelli 개발자 입니다. 그래도 intellij는 씁니다.

0개의 댓글