Zayson
A to Zayson!
Zayson
전체 방문자
오늘
어제
  • 분류 전체보기 (132)
    • Computer Science (20)
      • Network (4)
      • DB (12)
      • OS (4)
    • Algorithm (32)
      • 완전탐색(Brute-Force) (3)
      • 그리디(Greedy) (6)
      • 투포인터(Two-Pointer) (1)
      • 그래프(Graph) (5)
      • BFS & DFS (9)
      • 구현, 시뮬레이션(Implementation) (5)
      • 다이나믹 프로그래밍(DP) (3)
    • Backend (51)
      • Spring Boot (19)
      • JPA (16)
      • Kafka (2)
      • Java (13)
      • Kotlin (1)
    • DevOps (1)
      • Jenkins (5)
      • Oracle Cloud Infrastructure (1)
      • Kubernetes & Docker (1)
    • Trouble Shooting (3)
      • JPA (1)
      • Spring Boot (2)
    • 회고 (5)
      • 엔빵 프로젝트 포스트 로드맵 (1)
      • 2022년 (4)
    • Kafka (7)
      • Kafka (5)
      • Kafka Connect (2)
    • 기술 서적 (6)
      • 데이터 중심 애플리케이션 설계 (3)
      • 개발자가 반드시 정복해야할 객체 지향과 디자인 패턴 (2)
      • 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

  • 백준
  • kafka
  • 관계형 데이터베이스 실전 입문
  • JPA
  • 그리디
  • SpringBoot
  • Java
  • dfs
  • Computer science
  • CS
  • 라이브스터디
  • 구현
  • 엔빵프로젝트
  • BFS
  • 완전탐색
  • Backend
  • 나 혼자 스프링부트!
  • spring boot
  • Kafka Connect
  • 프로그래머스

최근 글

티스토리

hELLO · Designed By 정상우.
Zayson

A to Zayson!

상속관계 매핑
Backend/JPA

상속관계 매핑

2022. 7. 20. 11:07
  • 객체지향은 상속관계가 존재하지만 RDB는 상속 관계가 없다.
  • RDB에는 슈퍼타입/서브타입 관계같은 상속 관계와 비슷한 모델링 기법이 있다.
  • 물품을 RDB 논리 모델링을 진행하는 경우 물품 > 음반, 영화, 책 → 공통된 데이터를 물품이 갖는다 (슈퍼타입 / 서브타입)
  • 슈퍼타입/서브타입 → 객체 상속관계 변환 방법
    • 조인 전략 : 슈퍼타입용 테이블과 서브타입 테이블을 따로 구성하고, 슈퍼타입 테이블에 구분 컬럼을 둔다. 정규화가 잘 된 테이블 전략이다.
    • 단일 테이블 전략 (Default) : 서브타입 테이블 컬럼을 슈퍼타입 테이블 하나에 모은다. 구분 컬럼을 둔다. 성능적인 측면에서 장점이 있다.
    • 구현 클래스 별 테이블 전략 : 슈퍼타입의 공통 데이터를 서브타입 테이블에 컬럼으로 넣어 사용한다.

조인 전략

  • 정규화 모델링이 잘 된 테이블 전략
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item{
        @Id
    @GeneratedValue
    private Longid;

        private Stringname;
        private intprice;
}

@Entity
public class Movie extends Item {
    private String director;
    private String actor;
}
Movie movie = new Movie();
movie.setDirector("director A");
movie.setActor("actor B");
movie.setName("바람과 함께 사라지다.");
movie.setPrice(10000);

em.persist(movie);
  • 각각 Movie 테이블과 Item 테이블에 저장되고 Item 테이블의 PK가 Movie 테이블의 PK이면서 FK가 된다.
  • Movie를 조회하는 경우 Item을 JPA가 조인해서 가져온다.

  • @DiscriminatorColumn 서브타입의 테이블 명이 슈퍼타입의 DTYPE 컬럼에 들어간다. 해당 데이터가 어떤 서브타입에서 들어오는지 확인할 수 있다.
  • @DiscriminatorValue을 서브타입에 지정함으로써 테이블 명이 아닌 지정한 이름이 DTYPE에 들어가게 할 수 있다.

장점

  • 외래키 참조 무결성 제약조건을 활용 가능하기 때문에 다른 테이블에서 조회하고자 하는 경우 슈퍼타입 클래스의 PK만 알면 서브타입까지 조회하는 것이 가능하다.
  • 정규화가 되어있기 때문에 저장 공간에 있어 효율적이다.

단점

  • 조회 시 조인을 많이 사용하기 때문에 성능 저하가 있다.
  • 조회 쿼리가 복잡하고 insert 쿼리가 늘어난다.

 

단일 테이블 전략

  • 서브타입 테이블이 많아지는 경우 단일 테이블 전략을 이용하는 것이 장점이 될 수 있다.
  • 모든 컬럼을 슈퍼타입에 넣어 버리고 DTPYE을 이용해 어떤 서브타입의 데이터인지 구분한다.
  • @Inheritance의 Default 전략이다.
  • 조인이 없고, 데이터를 삽입할 때도 쿼리가 한번 밖에 안날아가기 때문에 성능적으로 장점이 있다.
  • 어떤 서브타입의 데이터인지 구분할 수없기 때문에 @DiscriminatorColumn을 생략해도 자동으로 추가된다.

장점

  • 하나의 테이블만 보고 조회를 할 수 있기 때문에 조회 쿼리가 단순하다.
  • 조인이 필요없기 때문에 조회 성능이 빠르다.

단점

  • 하나의 테이블로 사용하기 때문에 A 서브타입 데이터를 넣는 경우 B 서브타입의 데이터는 필요가 없고 데이터가 삽입되지도 않는다. 따라서, 서브타입 테이블 컬럼과 매핑한 엔티티는 모두 null을 허용한다.
  • 테이블 데이터가 많아지거나 서브타입이 많아지는 경우 데이터가 늘어나 조회 성능이 나빠질 수도 있다.

 

구현 클래스 별 테이블 전략 (실사용 X)

  • 슈퍼타입 테이블의 컬럼이 서브타입 테이블마다 포함되기 때문에 슈퍼타입 테이블이 존재하지 않는다.
  • @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 를 이용한다.
  • @DiscriminatorColumn이 필요가 없다.
  • 상위 클래스 타입으로 데이터를 조회하는 경우 JPA는 모든 서브타입 테이블을 union으로 가져와 조회하기 때문에 복잡하다.

장점

  • 서브타입을 명확하게 구분해서 처리할 수 있고, 구분되어 있기 때문에 Not Null을 사용하는 것이 가능하다.

단점

  • 여러 서브타입 테이블을 함께 조회할 때 Union을 이용한 쿼리를 실행하기 때문에 성능이 느리다.
  • 자식 테이블을 통합해서 쿼리를 실행하는 것이 복잡하다.

조인 전략? 단일 테이블 전략?

  • 조인 전략을 기본으로 선택해놓고, 해당 테이블이 확장 가능성 여부와 중요 여부를 판단해 단일 테이블 전략을 추후 선택하는 것을 권장한다.

 

@MappedSuperclass

  • DB내 테이블은 다른 테이블이지만 각 테이블에 공통되는 컬럼이 있어 객체입장에서는 공통 필드로 빼고 싶은 경우에 사용한다.
  • 상속관계 매핑이 아니다!
  • 직접 생성하고 조회 및 검색이 불가능하기 때문에 추상 클래스로 사용한다.
  • 부모 클래스를 상속받는 자식 클래스에 매핑 정보만 제공한다. 제공된 컬럼은 자식 엔티티와 매핑되는 테이블에 모두 포함된다.
@MappedSuperclass
public abstract class BaseEntity {

    //== 모든 테이블에 아래의 속성이 필수로 들어가야하는 경우 - 속성만 상속받아 사용 ==//
    private String createdBy;

    private LocalDateTime createdDate;

    @Column(name = "UPDATED_MEMBER")
    private String lastModifiedBy;

    private LocalDateTime lastModifiedDate;
}

 

 

  • 위의 BaseEntity 속성들이 BaseEntity를 상속받은 모든 엔티티 테이블에 포함된다.
  • JPA에서 엔티티가 상속을 받기 위해서는 @Entity 혹은 @MappedSuperclass가 붙어있는 엔티티 클래스만 상속이 가능하다.

 

📃 References

김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 : https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
반응형
저작자표시 비영리 변경금지 (새창열림)

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

즉시 로딩과 지연 로딩  (0) 2022.07.21
프록시  (0) 2022.07.20
엔티티 설계의 주의사항 간단 정리  (0) 2022.07.05
다양한 연관관계 매핑  (0) 2022.05.02
단방향, 양방향 매핑  (0) 2022.04.26
    'Backend/JPA' 카테고리의 다른 글
    • 즉시 로딩과 지연 로딩
    • 프록시
    • 엔티티 설계의 주의사항 간단 정리
    • 다양한 연관관계 매핑
    Zayson
    Zayson
    공부한 내용을 정리하는 공간

    티스토리툴바