[JPA] 다양한 연관관계 매핑 & 고급 매핑

Umji You·2021년 11월 10일
0

JPA기본

목록 보기
4/6

다양한 연관관계 매핑

1.다대일(N:1)


다대일 단방향(N:1)

  • 가장 많이 사용하는 연관관계
  • DB설계상 N : 1이므로, Member에 외래키가 있어야 한다.
    • 항상 DB는 N쪽에 외래키가 있는 것이 맞다.

다대일 양방향

  • 다대일 단방향에서 반대쪽에 연관관계 객체를 추가해주면 된다.
  • 하지만 반대쪽에서 추가한다고해서 DB테이블에 영향을 주지 않는다.
  • 연관관계가 주인이 아닌 쪽은 단순 조회만 가능하기에 필드만 추가해주면 된다.
    @OneToMany
    private List<Member> members = new ArrayList<>();

2.일대다(1:N)

일(One)이 연관관계의 주인이다.

  • 권장하는 방법은 아니다. 실무에서도 거의 사용되지 않음

  • 다대일 단방향의 반대이다.

  • 테이블 일대다 단방향 항상 다(N)쪽에 외래 키가 있는데, 일대다 단방향 매핑은 1:N 에서 외래키가 없는 쪽,일(1)이 연관관계의 주인(Team.members)이 된다.

  • @JoinColumn을 꼭 사용해야 한다. 그렇지 않으면 조인 테이블 방식을 사용하여 자동으로 중간에 테이블을 하나 추가한다.

결론 : 기본은 다대일(N:1)로 구현하다 필요에 의해 양방향 다대일(N:1)관계를 수립하도록 하자.

3.일대일(1:1)


  • 주 테이블외래 키
    • 주 객체가 대상 객체의 참조를 가지는 것처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾는다.
    • 객체지향 개발자가 선호한다.
    • JPA 매핑이 편리하다.
    • 장점
      • 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인이 가능하다.
    • 단점
      • 값이 없으면 외래 키에 NULL을 허용한다.
  • 대상 테이블외래 키
    • 대상 테이블에 외래 키가 존재한다.
    • 전통적인 DB 개발자가 선호한다.
    • 장점
      • 주 테이블과 대상 테이블을 1:1 에서 1:N 관계로 변경할 때 테이블 구조를 유지한다.
    • 단점
      • 주 테이블에는 외래키가 없기 때문에 대상 테이블이 있는지 없는지 알 수 없기 때문에 즉시 로딩이 무조건 된다.

4. 다대다(N:N)

관계형 DB는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다. 그래서 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야 한다.


다대다 매핑의 한계

  • 실무에서는 사용하지 않는다
  • 연결 테이블이 단순히 연결만 하고 끝나지 않는다.
  • 중간 테이블에 추가적인 데이터를 넣을 수 없다는 한계점이 존재한다.
  • 중간 테이블이 숨겨져 있기 때문에 의도치 않은 쿼리가 생성 될 수 있다.

다대다 한계 극복

  • 연결 테이블용 엔티티를 추가해 준다
    • 연결 테이블을 엔티티로 추가
  • @ManyToMany -> @OneToMany, @ManyToOne으로 바꿔준다.

5. 연관관계 매핑 어노테이션 속성


고급 매핑


상속관계 매핑

  • 관계형 데이터베이스는 상속관계가 없다.
  • 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 제일 유사!
  • 상속관계 매핑
    • 객체의 상속과 구조와 DB의 슈퍼타입 서브타입 관계를 매핑

슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법

1. 조인 전략

  • Item, Albun에 pk,fk가 같아 각각의 테이블에 insert를 수행하고 Item내에 타입을 구분하는 컬럼을 만들어서 구해온다.
  • 장점
    • 정규화도 되어있고, 제약조건을 부모에 걸어 맞출 수 있다.
    • 저장공간의 효율화
  • 단점
    • 조회시 조인이 많을 경우 성능이 저하된다.
    • 조회 쿼리가 복잡하다
    • 데이터 저장시 INSERT SQL2번 호출

조인이 많아도 조건이 잘 걸려있을 경우 성능 하락이 크지 않고 저장공간이 효율적으로 되기에 오히려 더 좋을 수 있다.

2. 단일 테이블 전략(Default)

  • 논리 모델을 한 테이블로 합쳐버리는 방법
  • 한 테이블에 다 넣어 놓고 어떤 테이블인지 구분하는 컬럼을 통해 구분한다.
  • 테이블은 ITEM 테이블 하나만 관리한다.
  • 성능에서 우위를 가질 수 있다.
    • select or insert가 한번에 수행된다.
  • @DiscriminatorColumn이 필수로 들어간다(기입하지 않아도 자동으로 들어간다.)
  • 장점
    • 조인이 필요 없기에 일반적으로 조회 성능이 빠르다.
    • 조회 쿼리가 단순하다.
  • 단점
    • 자식 엔티티가 매핑한 컬럼은 모두 NULLABLE 해야한다.
    • 단일 테이블에 모든 것을 저장하기에 테이블이 커질 수 있고 상황에 따라서 조회성능이 더 느려질 수 있다.

3. 구현 클래스마다 테이블 전략

  • 각각의 테이블마다 별개로 만들어서 따로 관리
  • ITEM 테이블을 생성하지 않고 ALBUM, MOVIE, BOOK 테이블에서 각각 id, name, price필드를 가지고 있다.
  • @DiscriminatorColumn을 사용할 수 없다.(구분 할 이유가 없다.)
  • ITEM을 조회하면 ALBUM, MOVIE, BOOK 세개의 테이블을 UNION ALL으로 전부 조회해서 가져온다.(단점)
  • 추천하지 않는 전략(개발자,DBA 양측에서)
  • 장점
    • 서브 타입을 명확하게 구분해서 처리할 때 효과적
    • Not null 제약조건 가능
  • 단점
    • 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL)
    • 자식 테이블을 통합해서 쿼리하기 힘듬.
profile
꾸준한 기록을 하자

0개의 댓글