본문 바로가기

JPA

[Spring JPA] JPA 상속 관계 매핑

냉장고 관리 어플리케이션 프로젝트에서

보관소를 냉장고, 냉동고, 실온 (세부 보관소)로 구분하는 작업을 진행하게 되었다..

이 관점에서 보면, 보관소는 큰 개념이고 냉장고, 냉동고, 실온 (세부 보관소) 들은

그 안에 속하는 서로 다른 유형이라는 생각이 들었고 설계를 할 때 어떤식으로 해야하는지에 대해서 고민을 하게 되었다..

 

 

(하나의 테이블을 가지고 필드하나로 구분할까?)

(각각의 테이블을 만들어서 설계하는 것이 용이한가...)

 

등등..

 

단순하게 생각을 했을 때 하나의 테이블에서 필드하나로 구분한다고 가정하면 매우 쉽다

하지만 추후 확장에 대해 문제점이 발생할 수 있다고 생각했다!!
초기에는 냉장고, 냉동고, 실온 저장소가

각각의 고유값, 보관소 이름, 저장공간 등과 같은 기본적인 옵션을 가지고 있을 수있다. 

그러나 나중에 냉장고, 냉동고, 실온 저장소를 별도로 관리해야 할 수도 있다.

 

 

냉장고는 추가로 온도 설정과 같은 특별한 속성을 가질 수 있고

냉동고 아이스메이커 유무 등

확장하게 된다면?

 

이때 테이블 하나에 각각의 추가 옵션 필드들을 넣어서 관리 한다면

값이 없는 보관소 같은 경우에는 null 값으로 

들어가게 될 것이고 관리나 정규화 측면에서 봤을 때 좋은 선택이 아니라고 생각했다.

물론 서비스의 규모가 크지 않고 큰 변동이 없다고 생각했을 때는 괜찮다고 생각했지만

팀원들과 이야기를 나눴을 때 기본적인 요구사항을 만든후

옵션들에 대해서 추가적으로 넣었으면 좋겠다는 이야기가 나왔다..

 

 

이러한 점을 고려하여 엔티티 설계에 대해서 이야기 해보고자 한다

일단 그 전에 관계형 데이터베이스 에서 테이블을 설계 할 때

위와 같은 방향으로 객체 구조를 설계하기 위해서는 

슈퍼타입 / 서브타입 모델링 방식과 유사하다.

 

 

                                                                                                                                                                      

여기서 관계형 데이터 베이스 관점이 아닌 객체의 관점에서 봤을 때

 

상속을 통해서 설계가 이루어진다.

상속관계 매핑이란?

더보기

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

  ♨                                                                                                                                                                    

 

상속관계 매핑의 장점

 

상속을 통해 부모 클래스StorageBox(세부 보관소)에 공통된 속성과 메서드를 정의하고,

이를 서브클래스에서 재사용함으로써 코드의 중복을 줄일 수 있다.

유지보수성을 향상시키고 코드의 일관성을 유지하는 데 좋다.


1. 객체 지향적 설계


 상속 관계 매핑은 데이터베이스의 테이블 간에 객체 간의 상속 구조를 반영하여 객체 지향적 설계를 유지할 수 있다

2.  유연성과 확장성

 

상속 관계를 사용하면 새로운 서브클래스를 추가하거나 기존 클래스를 수정하지 않고도 시스템을 확장할 수 있다.

 

3. 쿼리 작성의 편의성

상속 관계 매핑을 사용하면 부모 클래스에 정의된 속성을 기준으로 검색 및 조인을 수행할 수 있다.

 

상속 관계 매핑 전략

슈퍼타입과 서브타입 논리 모델을 가지고 물리 모델로 변환하고자 할 떄 변환 전략이 총 3가지가 존재한다.

쓰는 방법에 대해서는 검색을 통해 다양하게 알 수 있기 때문에

여기서는 간단하게 장단점을 이야기해보고 필자가 적용했던 전략을 이야기 해보겠다!!

 


1.Joined Table Inheritance

 

장점

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

단점

  • 데이터 조회 시 join 문이 날아가서 쿼리가 복잡해지고 성능이 떨어진다. (부모타입과 서브타입 둘다 찾아봐야함) 
  • 데이터 저장 시 insert 쿼리가 두 번 날라감

 

ITEM테이블과 하위 테이블에도 저장해야한다

똑같은 원리로 세부 보관소 부모 테이블에 저장 --> 하위 테이블 ( FRIDGE,FREEZE,ROOM) 에도 저장해야하기 때문에 

 

 

 

 

 

2. Single Table Inheritance

 

장점

  • 삽입 및 조회 쿼리가 한 번에 날라간다 (성능측면에서 조금 이득이 있다) --> join없을 때의 기준
  • 조회 쿼리를 작성하는데 있어서 단순하나 왜? 테이블이 하나이기 때문에

단점

  • null 값을 허용한다. 필자가 맨 위에 말했던 각각의 옵션에 null 값을 허용해야 함 (하나의 테이블을 사용하기 때문에) 
  • 테이블 하나에 모든 데이터를 저장하기 때문에 테이블이 커질 수 있다. 사오항에 따라서 조회 성능도 떨어질 수 있음

 

 

 

3.  Class Table Inheritance

 

 

장점

  • 서브 타입을 명확하게 구분해서 처리할 때 효과적 
  • 싱글 테이블 전략과는 다르게 not null 제약 조건 사용가능

단점

  • 여러 자식 테이블을 함께 조회할 때 성능이 느리다

UNION SQL 필요한데 여러 테이블을 UNION으로 연결하면 쿼리가 길어지고 가독성이 떨어질 수 있다.

  • 자식 테이블을 통합해서 쿼리하기가 어려움

다른 전략과는 달리  클래스마다 테이블 전략을 사용하는 것은 여러가지로 좋지 않기 때문에 잘 사용되지 않는다고 한다.

클래스마다 모든 테이블을 작성하는 방식이니깐 조회를 할 때 조금 문제가 생길듯 하다 ㅜ 

 

 

 

 

필자는 단일 테이블 전략과 조인 전략을 고민하던 중에 조인 전략을 선택했다

성능적인 면에서는 단일 테이블 전략을 사용하는 것이 

더 좋다고는 알고 있었지만 

세부 보관소의 추가 옵션이나 

테이블 정규화를 좀 더 우선순위를 두고 생각해서 

조인 전략을 생각했다

두개의 전략의 차이는 서비스의 규모나 생각하는 관점에  따라서 선택하면 될 것 같다