Post

(JPA)상속관계 매핑

상속관계 매핑

  • 관계형 데이터베이스는 상속 관계가 없다.
  • 슈퍼타입, 서브타입 관계라는 모델링 기법이 객체 상속과 유사하다.
  • 상속관계 매핑: 객체의 상속 구조와 DB의 슈퍼타입, 서브타입 관계를 매핑

슈퍼, 서브타입 논리 모델을 물리 모델로 구현

  • 각각 테이블로 변환 -> 조인 전략
  • 통합 테이블로 변환 -> 단일 테이블 전략(JPA 기본 전략)
  • 서브타입 테이블로 변환 -> 구현 클래스 마다 테이블을 두는 전략

주요 어노테이션

  • @Inheritance(strategy = InheritanceType.XXX)
    • JOINED: 조인 전략
    • SINGLE_TABLE: 단일 테이블 전략
    • TABLE_PER_CLASS: 구현 클래스 마다 테이블을 두는 전략
  • @DiscriminatorColumn(name = “DTYPE”)
  • @Discriminator(“XXX”)

조인 전략

  • @Inheritance(strategy = InheritanceType.JOINED)

Item

  • @DiscriminatorColumn 어노테이션을 명시 하지 않아도 정상적으로 작동하지만, 운영상 넣어주는 것이 좋다.
    • 조인이 이뤄졌을때 DB 관점에서 어떤 테이블로의 조인이 이뤄지는지 명확하게 알기 어렵기 때문이다. ```java @Entity @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = “DTYPE”) public abstract class Item { @Id @GeneratedValue private Long id;

    private String name; private int price; } ```

Album

1
2
3
4
5
@Entity
@DiscriminatorValue("A")
public class Album extends Item {
    private String artist;
}

Movie

1
2
3
4
5
6
@Entity
@DiscriminatorValue("M")
public class Movie extends Item {
    private String director;
    private String actor;
}

Book

1
2
3
4
5
6
@Entity
@DiscriminatorValue("B")
public class Book extends Item {
    private String author;
    private String isbn;
}

조인 전략의 장점

  • 테이블이 정규화 되어 있다.
  • 외래 키 참조 무결성 제약조건을 활용할 수 있다.
  • 저장 공간이 효율적이다.

조인 전략의 단점

  • 조회 시 조인을 많이 사용, 성능 저하
  • 조회 쿼리가 복잡하다.
  • 데이터 저장 시 INSERT SQL 2번 호출

단일 테이블 전략

  • Item 엔티티에 붙어있는 @Inheritance(strategy = InheritanceType.XXX)@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 로 변경해주면 된다.
  • @DiscriminatorColumn 어노테이션을 명시해주지 않아도, DTYPE 컬럼을 만들어 준다.
  • 단일 테이블 전략에서는 DTYPE이 필수
    • 하나의 테이블을 사용하기 때문에 값을 구분해줄 수 있는 컬럼이 필요하기 때문이다.

단일 테이블 전략의 장점

  • 조인이 필요 없어 조회 성능이 좋다.
  • 조회 쿼리가 매우 단순하다.

단일 테이블 전략의 단점

  • 자식 엔티티가 모든 컬럼에 대해 NULL 값을 허용해 줘야 한다.
  • 단일 테이블에 모든 것을 저장하기 때문에 테이블이 커질 수 있으며, 상황에 따라 조회 성능이 느려질 수 있다.

구현 클래스 마다 테이블을 생성하는 전략

  • Item 엔티티에 붙어있는 @Inheritance(strategy = InheritanceType.XXX)@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 로 변경해주면 된다.
  • @DiscriminatorColumn 어노테이션은 필요가 없다.
  • 사용하면 안되는 전략

구현 클래스 마다 테이블을 생성하는 전략의 장점

  • 서브 타입을 명확하게 구분해서 처리할 때 효과적이다.
  • NOT NULL 제약조건을 사용 할 수 있다.

구현 클래스 마다 테이블을 생성하는 전략의 단점

  • 여러 자식 테이블을 함께 조회할 때 성능이 매우 안좋다.
    • UNION SQL 을 사용하기 때문에
  • 자식 테이블을 통합해서 쿼리 하기 어렵다.
  • 변경이 매우 어렵다.
This post is licensed under CC BY 4.0 by the author.