지도에 마킹이 가능한 두개의 엔티티, CultureEvent와 CulturePlace는 Mark 엔티티를 상속하고 있다.
이러한 상속관계에서 선택하기 적절한 상속관계매핑전략은 조인 전략, 싱글테이블 전략 두가지가 있는데 이번에 나는 싱글테이블 전략을 선택하기로 했다.
먼저 총 3개의 상속관계 매핑 전략을 읊고 가자.
🪄상속관계 매핑 전략
조인 전략:
자식테이블이 부모테이블의 PK를 참조한다. 즉 자식테이블의 PK는 FK다.
부모테이블은 DTYPE (구분 컬럼)을 가진다. 어떤 자식테이블을 조회해야할지 알아야 하기 때문.
장점: 가장 정규화된 방법이다. 외래키 참조 무결성 제약조건도 활용 가능하고, 저장공간도 효율적으로 사용 가능하다.
단점: 조회시 Join이 잦아 성능저하를 검토해야 한다. Join을 하기에 조회쿼리도 복잡해진다. 데이터를 등록할 때 당연히 insert문도 두번 실행된다.
싱글 테이블 전략:
하나의 테이블에 다 넣는다. 데이터의 구분은 DTYPE 구분컬럼을 통해 한다.
장점: 조인전략과 달리 Join이 사용될 여지가 없어 조회성능이 빠르고 조회 쿼리도 단순!
단점: 자식 엔티티 컬럼값들은 모두 NULL이 허용된다. 또한 아무래도 하나의 테이블에 모든 속성, 모든 레코드를 넣기 떄문에 테이블이 커질 수 있는데, 너무 커지면 조회 성능이 좋지 않을 수 있다.
구현클래스마다 테이블을 두는 전략
자식엔티티마다 테이블을 생성하는 전략이다. 부모든 자식이든 그 데이터의 PK를 갖고 있으면 된다.
단점: 여러 자식 테이블을 함께 조회시 UNION을 사용하며 성능문제가 있다. 자식테이블을 통합해 쿼리 작성하는 것이 번거롭다.
🪄 싱글 테이블 전략을 선택한 이유
미래와 현재를... 생각해봤다.
[현황]
일단 Mark 데이터는 하루에 한번만 업데이트하기 때문에, 조회를 하루에 한번만 하면 된다. (메모리에 올려두므로)
또한 Mark의 자식들을 구분하여 서비스하고있지 않아서.. 조회 성능이 좋다는 것이 가장 우선순위의 선택지였다.
굳이 Join을 거쳐가는 것이 불필요하다고 생각했다.
[미래 가능성]
부모 클래스는 Mark이고 자식 클래스는 CultureEvent, CulturePlace인 상황에서, 두 자식 클래스가 추가적인 필드를 가지고 있지 않아서 의미 없는 NULL값이 자리를 차지하지 않는다. 만약 앞으로 추가되더라도 한두개 추가될 뿐이다.
// 상위클래스: Mark
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public class Mark {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "mark_id")
private Long id;
...
}
// 하위클래스1: CultureEvent
@Entity
public class CultureEvent extends Mark{ }
// 하위클래스2: CulturePlace
@Entity
public class CulturePlace extends Mark { }
🪄 미래 상황을 고려해보자
나중에 Mark의 자식들에 대한 개별 관리, 개별 서비스가 필요하다면 + 데이터가 방대해진다면
조인 전략이 나을 것인가, 싱글 테이블 전략이 나을 것인가?
지금은 서울의 데이터를 대상으로 하고 있지만, 만약 전국으로 확대된다면 데이터가 꽤나 커질 것이다.
저장효율과 조회효율을 고려해보자.
음.. 지금 서울시 데이터가 대략 1500건인데, 전국으로 한다고 해도 몇만건밖에 안될 것이다.
그러면 하나의 테이블에 저장해도 그리 방대해지 않다.
조회할 때도 마찬가지다. 만약 지역별로 조회할 일이 생긴다면, 굳이 조인을 하는 것보다는 하나의 테이블에서 지역 필터링해서 조회하는 것이 나을 것이다.
그때도 여전히 싱글 테이블 전략을 선택할 듯하다!
'Database' 카테고리의 다른 글
DB 데이터 변경 감지 방법 | 폴링 or 이벤트 (2) | 2024.11.29 |
---|---|
MSA에서 분산트랜잭션 (0) | 2024.05.22 |
[MySQL + JPA] field 'mark_id' doesn't have a default value | 그리고 auto increment (0) | 2024.05.11 |
컬럼 수 적절성에 대한 고민 및 테이블 분할 (0) | 2024.04.15 |
Docker Mysql Container의 sql 파일 꾸준히 백업: crontab 사용 (0) | 2024.01.04 |