Home 상속관계 매핑
Post
Cancel

상속관계 매핑

상속관계 매핑

객체에는 상속이라는 개념이 있다. 하지만 관계형 데이터베이스에는 상속 관계라는 개념이 없다.

관계형 데이터베이스의 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속관계와 유사하다.

따라서 상속관계 매핑이란 아래와 같다.

  • 상속관계 매핑
    • 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑하는 것을 의미한다.

  • 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법 3가지
    • 조인 전략
    • 단일 테이블 전략
    • 구현 클래스마다 테이블 전략

주요 어노테이션

  • @Inheritance(strategy = InheritanceType.xx)
    • JOINED: 조인 전략
    • SINGLE_TABLE: 단일 테이블 전략
    • TABLE_PER_CLASS: 구현 클래스마다 테이블
  • @DiscriminatorColumn(name=”DTYPE”)
    • 타입 구분을 위한 구분컬럼(DTYPE - 기본) 생성
    • 컬럼 이름 변경 가능
    • 부모 엔티티에 사용
  • @DiscriminatorValue(“xx”)
    • 구분자 이름 설정
    • 상속받는 엔티티에 사용

조인 전략

가장 정교화된 방식이다.

중복되는 Name, Price 등은 Item 테이블에 있다. 그리고 위의 예시에서는 DTYPE 이라는 어떤 구분자를 통해 어떤 아이템 타입인지 구분한다.

중복되지 않는 Director 같은 컬럼은 각각의 아이템 타입 테이블에 존재하는 구조이다.

이러한 구조에서 조회할 경우 join 방식으로 조회하게 된다.

1
2
3
4
5
6
7
8
9
10
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public abstract class Item {
	@Id @GeneratedValue
	private Long id;

	private String name;
	private int price;
}
1
2
3
4
5
@Entity
@DiscriminatorValue("A")
public class Album extends Item {
	private String artist;
}
1
2
3
4
5
6
7
@Entity
@DiscriminatorValue("B")
public class Book extends Item {
	
	private String author;
	private String isbn;
}
  • 장점
    • 테이블 정규화
    • 외래 키 참조 무결성 제약조건 활용 가능
    • 저장공간 효율화
  • 단점
    • 조회 시 조인을 많이 사용해 성능 저하 (큰 저하는 X)
    • 조회 쿼리가 복잡하다.
    • 데이터 저장 시 Insert SQL을 2번 호출한다.

가장 추천되는 전략이다.

단일 테이블 전략

하나의 테이블에 모든 컬럼을 다 넣어두고 DTYPE 이라는 컬럼으로 구분하는 방법.

조인 전략에서 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)로만 바꾸어 주면 된다.

단일 테이블 전략은 @DiscriminatorColumn 애노테이션을 붙이지 않아도 자동으로 구분 컬럼이 생성된다.

  • 장점
    • 조인이 필요 없어 일반적으로 조회 성능이 빠르다.
    • 조회 쿼리가 단순하다.
  • 단점
    • 자식 엔티티가 매핑한 컬럼은 모두 null이 허용된다.
    • 단일 테이블에 모든 것을 저장하므로 테이블이 커져 상황에 따라서 조회 성능이 오히려 느려질 수 있다.

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

다른 방법들과 다르게 Item이라는 테이블을 만들지 않고, 하위 타입마다 각각의 테이블을 두는 전략이다.

1
2
3
4
5
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Item {
	//...
}

InheritacneType을 바꾸어주면 된다.

각각의 전략을 바꿀 때 간편하게 바꿀 수 있는 것을 볼 수 있다. JPA를 사용하지 않고 바꾼다고 생각하면 매우 많은 부분을 수정해야 할 것이다.

삽입이나 특정 데이터를 집어서 조회할 때에는 문제가 없다.

하지만 만약 임의의 아이템 아이디 5번을 조회하고 싶다 라는 상황을 가정해보면 5번 아이템이 어떤 테이블에 있는 지 모르므로 각각의 테이블을 모두 조회해보아야 한다는 문제가 생긴다.

굉장히 비효율적인 것이다.

따라서 이 전략은 추천되지 않는다.

  • 장점
    • 서브 타입을 명확하게 구분해 처리할 때 효과적이다.
    • not null 제약조건을 사용 가능하다.
  • 단점
    • 여러 자식 테이블을 함께 조회할 때 성능이 느리다. (UNION SQL 사용)
    • 자식 테이블을 통합해 쿼리하기 어렵다.
This post is licensed under CC BY 4.0 by the author.