반응형
JPA의 상속 매핑 전략
JPA에서는 객체지향 언어에서 제공하는 상속(Inheritance) 개념을 관계형 데이터베이스 위에서도 그대로 표현할 수 있도록 상속 매핑 전략을 제공합니다.
하지만 DB는 상속 개념이 없기 때문에, 이를 다음의 세 가지 전략으로 풀어냅니다.
1. JOINED 전략 (@Inheritance(strategy = JOINED))
가장 정규화된 방식
- 공통 속성은 Item 테이블에 저장하고
- 개별 속성은 Album, Book, Movie 테이블에 저장
- 각 자식 테이블은 ITEM_ID를 외래키로 가지며
- 조회 시 JOIN으로 연결
- ITEM 입장에서 어떤 타입의 데이터인지 알 수있게 DTYPE으로 구분할 수 있음 (넣는것을 권장)
@Entity
@Ingeritance(strategy = IngeritanceType.JOINED) // 해당 값이 없으면 기본 한테이블에 다 넣는 2번방식
@DiscriminatorColumn // 해당 값이 있으면 DTYPE이 생김
public abstract class Item { // 추상클래스로 안하면 > ITEM을 독단적으로 쓰는 경우가 있다고보고 생성하는것 추상클래스로 만들자
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@Entity
// @DiscriminatorValue("A") 값으로 DTYPE값을 변경 가능
public class Album extends Item {
private String artist;
}
@Entity
pulbic class Moview extends Item {
private String director;
private String actor;
}
장점
- 테이블이 정규화되어 있어 무결성 보장
- NOT NULL, FK, 유니크 제약조건 사용 가능
- 저장공간 효율화
단점
- JOIN이 많아져 조회 성능 저하 가능 (조회 쿼리가 복잡)
- INSERT 시 부모 테이블과 자식 테이블에 2번 INSERT
2. 단일 테이블 전략 (@Inheritance(strategy = SINGLE_TABLE))
모든 데이터를 한 테이블에 넣는 방식 (주로 프로젝트가 단순하거나, 복잡한 테이블 구조가 필요없을 때 사용)
- DTYPE으로 구분
- 공통 컬럼 + 각 타입별 컬럼 모두 포함됨
- 관련 없는 데이터는 NULL 처리됨
@Entity
@Ingeritance(strategy = IngeritanceType.SINGLE_TABLE) //혹은 생략
@DiscriminatorColumn // 해당 값이 없어도 무조건 생김 = DTYPE이 없으면 누가 누군지 몰라서 필수임
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
장점
- 조인이 없기 때문에 조회 성능 우수
- 쿼리 단순함
단점
- null 칼럼 다수 발생
- 테이블이 점점 넓어짐 (column 수 증가) → 인덱싱 비효율
- 구조상 제약 조건 사용 제한
3. 구현 클래스마다 테이블 전략 (@Inheritance(strategy = TABLE_PER_CLASS))
자식 클래스마다 완전한 테이블을 따로 생성 (비추천)
@Entity
@Ingeritance(strategy = IngeritanceType.TABLE_PER_CLASS)
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
※ 추상클래스를 사용하지 않으면, ITEM 테이블이 단독으로 생길수 있으니 주의!
이 전략은 절대 실무에서 쓰지 말자
- 부모 타입으로 조회하면 UNION ALL 쿼리 발생
→ SELECT * FROM album UNION ALL SELECT * FROM movie ...
Item item = em.find(Item.class, move.getId());
System.out.println("Item = " + item);
- DTYPE 사용하지 않음
장점
- 서브타입 명확히 분리
- 각 테이블 독립적 → NOT NULL, 유니크 키 사용 가능
단점
- 통합 조회 어렵고 성능 저하
- 변경 시 확장성, 유지보수 최악 (테이블 변경시 비즈니스 로직 변경되어야함)
반응형
'프로그래밍 > JPA' 카테고리의 다른 글
[JPA] 프록시와 연관관계 관리 (0) | 2025.07.15 |
---|---|
[JPA] Mapped Superclass - 매핑 정보 상속 (0) | 2025.07.03 |
[JPA] 다양한 연관관계 매핑 (2) | 2025.06.30 |
[JPA] 양방향 연관관계와 연관관계의 주인[2] (0) | 2025.06.25 |
[JPA] 양방향 연관관계와 연관관계의 주인[1] (1) | 2025.06.24 |