[Spring boot] 고급 매핑

어정윤·2021년 7월 31일
0

Spring boot 스터디

목록 보기
6/15
post-thumbnail

[Spring boot] 고급 매핑

상속 관계 매핑

관계형 데이터베이스에는 상속 개념이 없다. 대신 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속 개념과 가장 유사하다.

상속 관계 매핑이란 객체의 상속 구조와 데이터베이스의 슈퍼타입 서브타입 관계를 매핑하는 것이다.

슈퍼타입 서브타입 논리 모델을 실제 물리 모델(테이블)로 구현하는 방법

  1. 각각의 테이블로 변환 : 조인 전략
  2. 통합 테이블로 변환 : 단일 테이블 전략
  3. 서브타입 테이블로 변환 : 구현 클래스마다 테이블 전략

주요 어노테이션

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

조인 전략

조인 전략은 엔터티 각각을 모두 테이블로 만들고 자식 테이블이 부모 테이블의 기본 키를 받아서 기본 키 + 외래 키로 사용하는 전략이다. 따라서 조회할 때 조인을 자주 사용한다.

객체는 타입으로 구분할 수 있지만 테이블은 타입의 개념이 없으므로 타입을 구분하는 컬럼을 추가해야 한다. 여기서는 DTYPE 컬럼을 구분 컬럼으로 사용한다.

상속 매핑은 부모 클래스에 @Inheritance를 사용해야 한다. 그리고 매핑 전략은 조인 전략을 사용하므로 InheritanceType.JOINED를 사용

또한 부모 클래스에 구분 컬럼을 지정해야 한다. 이 컬럼으로 저장된 자식 테이블을 구분할 수 있다. 기본값이 DTYPE이므로 @DiscriminatorColumn으로 줄여서 사용해도 된다.

엔터티를 저장할 때 구분 컬럼에 입력할 값을 지정한다. 만양 영화 엔터티를 @DiscriminatorValue("M")으로 저장하면 구분 컬럼인 DTYPE에 값 M이 저장된다.

기본 값으로 자식 테이블은 부모 테이블의 ID 컬럼명을 그대로 사용하는데, 만약 자식 테이블의 기본 키 컬럼명을 변경하고 싶으면 @PrimaryKeyJoinColumn(name = "XXX")을 사용하면 된다.

조인 전략의 장점

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

조인 전략의 단점

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

+ JPA 표준 며세는 구분 컬럼을 사용하도록 하지만 하이버네이트를 포함한 몇몇 구현체는 구분 컬럼(@DisciriminatorColumn) 없이도 동작한다.

단일 테이블 전략

단일 테이블 전략은 이름 그대로 테이블을 하나만 사용한다. 그리고 구분 컬럼으로 어떤 자식 데이터가 저장되었는지 구분한다. 조회할 때 조인을 사용하지 않으므로 일반적으로 가장 빠르다.

단일 테이블 전략 사용시 자식 엔터티가 매핑한 컬럼은 모두 null을 허용해야 한다.

단일 테이블 전략은 테이블 하나에 모든 것을 통합하므로 구분 컬럼을 필수로 사용해야 한다.

단일 테이블의 장점

  • 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
  • 조회 쿼리가 단순

단일 테이블의 단점

  • 자식 엔터티가 매핑한 컬럼은 모두 null 허용
  • 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있음 -> 상황에 따라서 조회 성능이 오히려 느려질 수 있음

+ 구분 컬럼을 꼭 사용해야 하므로 @DiscriminatorColumn을 꼭 설정해야 한다.
+ @DiscriminatorValue를 지정하지 않으면 기본으로 엔터티 이름ㅇ르 사용한다.

구현 클래스마다 테이블 전략

구현 클래스마다 테이블 전략은 자식 엔터티마다 테이블을 만든다. 그리고 자식 테이블 각각에 필요한 컬럼이 모두 있다.

이 전략은 일반적으로 추천하지 않는 전략이다.

구현 클래스마다 테이블 전략의 장점

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

구현 클래스마다 테이블 전략의 단점

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

@MappedSuperclass

@MappedSuperclass 어노테이션은 테이블과 관계가 없고, 단순히 엔터티가 공통으로 사용하는 매핑 정보가 필요할 때 사용한다.

이는 추상 클래스와 비슷하다. @Entity는 실제 테이블과 매핑되지만 @MappedSuperclass는 실제 테이블과는 매핑되지 않는다. 단순히 매핑 정보를 상속할 목적으로만 사용된다.

정리

  • 상속관계 매핑X
  • 엔터티X, 테이블과 매핑X
  • 부모 클래스는 상속 받는 자식 클래스에 매핑 정보만 제공
  • 조회, 검색 불가(em.find(BaseEntity) 불가)
  • 직접 생성해서 사용할 일이 없으므로 추상 클래스 권장

+ @Entity 클래스는 엔터티나 @MappedSuperclass로 지정한 클래스만 상속 가능

조인 테이블

데이터베이스 테이블의 연관관계를 설계하는 방법은 크게 2가지다.

  1. 조인 컬럼 사용(외래 키)
  2. 조인 테이블 사용(테이블 사용)

조인 컬럼 사용

테이블 간에 관계는 주로 조인 컬럼이라 부르는 외래 키 컬럼을 사용해서 관리한다.

조인 컬럼은 주로 일대일 혹은 일대다 관계에서 사용한다.

조인 테이블 사용

조인 테이블이라는 별도의 테이블을 사용해서 연관관계를 관리한다.

조인 컬럼을 사용하는 방법은 단순히 외래 키 컬럼만 추가해서 연관관계를 맺지만 조인 테이블을 사용하는 방법은 연관관계를 관리하는 조인 테이블을 추가하고 여기서 두 테이블의 외래 키를 가지고 연관관계를 관리한다.

조인 테이블은 주로 다대다 관계를 일대다, 다대일 관계로 풀어내기 위해 사용한다.

profile
성장ing

0개의 댓글