상속관계 매핑 정의
관계형 데이터베이스는 상속관계가 존재하지 않는다.
대신 DB의 슈퍼-서브타입 모델링 기법이 객체 상속 관계와 유사하기 때문에 매핑해서 쓸 수 있다.
한 마디로 상속 관계 매핑은 상속 관계와 슈퍼-서브 타입 관계를 매핑하는 것이다.
아래 그림처럼 음반, 영화, 책에서 공통적인 속성을 뽑아내어 물품을 만들 수 있다.

슈퍼-서브타입 논리 모델을 실제 물리 모델로 구현하는 방법은 총 3가지가 있다.
아래에서 하나씩 살펴보자.
조인 전략
조인으로 데이터를 정규화하여 구성하는 전략이다.
공통 속성인 name, price는 Item 테이블에 저장되고, 나머지 속성들은 각 테이블에 저장된다.

코드
각 엔티티를 생성해준다.
Item엔티티는 상속해 주는 용도로만 쓰이므로 추상 클래스로 정의했다.
@DiscriminatorColumn을 매핑하여 구분자 DTYPE 컬럼을 추가했다.
조인 전략에서는 해당 어노테이션이 없으면 DTYPE 컬럼이 생성되지 않는다.
@Entity
@Inheritance(strategy = InheritanceType.JOINED) // 조인전략
@DiscriminatorColumn
public abstract class Item{
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
상속받는 클래스는 @DiscriminatorValue로 직접 DTYPE을 정해줄 수 있으며 default는 엔티티명이다.
@Entity
@DiscriminatorValue("M")
public class Album extends Item {
private String artist;
}
Movie객체를 저장하면 Item, Movie에 각각 insert 쿼리가 나간다.

데이터 조회 시 ITEM_ID로 조인하고, DTYPE으로 하위 객체들을 구분한다.

단일 테이블 전략
단일 테이블 전략에서는 논리 모델을 한 테이블에 다 합치고, 하위 객체들을 DTYPE으로 구분한다.

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
위 어노테이션만 변경하면 단일 테이블 전략이 된다.
DDL을 확인해보면, ITEM 테이블만 생성된다.
한 테이블에 모든 컬럼을 저장하기 때문에 DTYPE이 없이는 구별할 수 없다.
그래서 @DiscriminatorColumn이 없어도 DTYPE이 자동으로 생성된다.

Movie에 값을 넣어주면 아래와 같은 insert 쿼리가 실행된다.
다른 두 전략과 비교했을 때 삽입 쿼리와 조회 쿼리가 단순하고, 조인할 필요가 없어 성능이 좋다.


구현 클래스마다 테이블 전략
서브 타입 테이블로 변환하는 전략이다.
슈퍼 타입의 컬럼들을 서브 타입으로 내린다.
따라서 각 테이블에서 중복된 속성 name, price를 가지고 있다.

아래 어노테이션을 매핑하면 구현 클래스마다 테이블 생성 전략을 쓸 수 있다.
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
구분자가 필요 없으므로 @DiscriminatorColumn이 사용되지 않는다.
DDL을 확인해보면 조인 전략 때와 달리 name, price는 Item이 아닌 Album에 들어있다.

이 전략은 성능이 느리고 하위 클래스가 추가되면 변경하기 어렵기 때문에 사용하지 말자.
주요 어노테이션
- @Inheritance(strategy = InheritanceType.XXX)
- JOINED: 조인 전략
- SINGLE_TABLE: 단일 테이블 전략
- TABLE_PER_CLASS: 구현 클래스마다 테이블 전략
- @DiscriminatorColumn(name = "DTYPE")
- @DiscriminatorValue("XXX")
정리
조인 전략

장점
- 테이블이 정규화되어 있다.
- 외래키 참조 무결성 제약 조건을 활용할 수 있다.
다른 엔티티에서 아이템을 참조할 때 서브 타입까지 갈 필요 없이, 슈퍼 타입의 아이디만 확인하면 된다.
- 저장 공간을 효율화할 수 있다.
단점
- 조회 시 조인을 많이 사용해 성능이 저하된다.
- 조회 쿼리가 복잡하다.
- 데이터 저장 시 INSERT SQL이 2번 호출된다.
단일 테이블 전략

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

장점
- 서브 타입을 명확히 구분하여 처리할 수 있다.
- NOT NULL 제약 조건을 사용할 수 있다.
단점
- 여러 자식 테이블을 함께 조회할 때 성능이 느리다.
- 자식 테이블을 통합해서 쿼리하기 어렵다.
결론
구현 클래스마다 테이블 생성 전략은 성능이 느리고 변경이 어렵기 때문에 사용하지 말자.
조인 전략과 단일 테이블 전략의 trade off를 고민해봐야 한다.
프로젝트가 단순하고 확장 가능성이 적으면 단일 테이블 전략을 사용하자.
비즈니스적으로 중요하고, 복잡하며, 확장될 가능성이 높으면 조인 전략을 사용하자.
Reference
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의
초급자를 위해 준비한 [웹 개발, 백엔드] 강의입니다. JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자
www.inflearn.com