[JPA] 상속관계 매핑

동동·2022년 4월 21일

JPA

목록 보기
7/18
post-thumbnail

상속관계 매핑

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

슈퍼타입 / 서브타입 논리모델을 실제 물리 모델로 구현하는 방법

총 3가지의 방법이 있다.

  • 각각 테이블로 변환 -> 조인 전략(Joined Strategy)
  • 통합 테이블로 변환 -> 단일 테이블 전략(Single-Table Strategy)
  • 서브타입 테이블로 변환 -> 구현 클래스마다 테이블 전략(Table-per-Concreate-Class Strategy)

🚧 구현 어노테이션

  • @Inheritance(strategy=InheritanceType.XXX)
    • JOINED : 조인 전략
    • SINGLE_TABLE : 단일 테이블 전략
    • TABLE_PER_CLASS : 구현 클래스마다 테이블 전략

📌 조인 전략(Joined Strategy)

조인 전략은 아이템이라는 테이블을 만들고 앨범, 무비, 북 테이블을 각 각 만들고 join을 사용해서 데이터를 가지고 옴.

  • 장점

    • 테이블 정규화
    • 외래 키 참조 무결성 제약조건 활용가능
    • 저장공간 효율화
  • 단점

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

🚧 DTYPE

DTYPE이란 컬럼을 두어서 그게 앨범인지 무비인지 북인지 구분함.
DTYPE이 없으면 ITEM 클래스 데이터가 앨범 / 무비 / 북 중 어떤 것 때문에 들어왔는지 모름
@DiscriminatorColumn -> 부모 클래스에 이 어노테이션을 사용하면 됨
@DiscriminatorValue("Book") -> 자식 클래스에는 DTYPE 이름을 지정해줌
조인전략에서는 DTYPE 생략해도 되나 single-table 전략에서는 꼭 넣어줘야함

📌 단일 테이블 전략(Single-Table Strategy)

모든 테이블은 한 클래스에 다 때려넣음
DTYPE을 작성 안해도 단일 테이블전략을 쓰면 알아서 생성됨
조회를 할 때 join 쿼리가 필요없음

  • 장점
    • 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
    • 조회 쿼리가 단순함
  • 단점
    • 자식 엔티티가 매핑한 컬럼은 모두 null 허용(데이터 무결성을 보장할 수 있는가?)
    • 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있고 상황에 따라서 조회 성능이 오히려 느려질 수 있다.

📌 구현 클래스마다 테이블 전략(Table-per-Concreate-Class Strategy)

DB 설계자와 ORM 전문가 둘 다 추천하지 않음
쓰면 안된다...
DB 측면에서도 ORM 측면에서도
공통 컬럼은 테이블마다 각각 가지고 감
부모 테이블인 Item은 생성되지 않고 자식 테이블들만 생성됨
그리고 그 자식 테이블에 부모테이블의 속성이 각 각 들어감
단순하게 insert/select할 때는 좋음
시스템 변경 입장에서 볼 때 좋지않음(유지보수 어려움)

  • 장점

    • 서브 타입을 명확하게 구분해서 처리할 때 효과적
    • not null 제약조건 사용가능
  • 단점

    • 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)
    • 자식 테이블을 통합해서 쿼리하기 어려움

Album / Movie / Book 중 무엇을 조회하는 건지 딱 집어서 조회하는건 O

Movie movie = em.find(Movie.class, movie.getID());

하지만 부모 클래스(Item)으로 조회 했을 때는 모든 자식테이블을 다 뒤져봐야함

Item item = em.find(Item.class, movie.getID());

union all select로 모든 테이블을 다 조회함

profile
괴발개발

0개의 댓글