다양한 연관관계 매핑
in Framework on Spring Data JPA
다대일 N:1
가장 이상적인 매핑 형태.
N에 해당하는 테이블이 FK를 갖는 구조이며 N에 해당하는 클래스가 연관관게의 주인이 된다.
이 방법이 가장 이상적인 이유는, FK를 가진 쪽에서 연관관계의 주인이 되기 때문에 주인 클래스의 변경이 곧 업데이트가 된다.
반대로 1에 해당하는 클래스는 readOnly가 된다.
일대다 1:N
위 다대일과는 반대로 1이 연관관계의 주인이 되는 구조.
이 구조는 FK를 N이 갖고 있기 때문에 반대편 테이블이 외래 키를 관리하는 특이한 구조가 된다.
조심할 점은 @JoinColumn
을 사용하지않으면 조인 테이블을 만들어 사용해버린다.
일대일 1:1
어느쪽에 FK를 가져도 상관은 없다.
JPA에서 단방향 관계는 지원하지 않으며 양방향 관계를 지원한다.
외래키를 어디다 두는 것이 좋을지는 개발자의 판단에 따라 다르다.
미래를 보고, 1:1 관계에서 N이 될 가능성이 높은 쪽에 FK를 놓는 것이 유리할 수 있다.
그러나 이 역시 상황에 따라 다르기 때문에 외래키를 어느 쪽에 둘 지는 그 테이블에 매핑된 객체를 얼마나 자주 사용하는지에 따라 지정할 수도 있다.
자주 사용하는 테이블을 주 테이블이라고 하고, 그 테이블의 대상이 되는 테이블을 대상 테이블이라고 하면 다음과 같은 장단점이 존재한다.
주 테이블에 외래키
주 객체가 대상 객체의 참조를 가지는 것 처럼 주 테이블에 외래키를 두고 대상 테이블을 찾게 한다.
장점은 객체지향 개발자가 선호하는 방식이며 주 테이블만 조회해도 대상 테이블의 데이터가 있는지 확인이 가능하다.
단점은 값이 없으면 외래키에 null을 허용해야한다.
대상 테이블에 외래키
대상 테이블에 외래키를 넣으며 DBA가 좋아하는 방식이다.
장점은 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테입르 구조를 유지할 수 있다.
단점으로는 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩된다.
다대다 N:M
한 줄 요약 : 실무에서 쓰면 안된다.
Why?
관계형 DB에서는 정규화된 테이블 2개를 다대다 관계로 표현할 수 없다.
연결 테이블을 추가해 일다, 다대일 관계로 풀어내야한다.
객체는 컬렉션을 사용해 객체 2개로 다대다 관계가 가능하다.
이 다대다 매핑이 편리해보이지만 실무에선 사용할 수 없는 이유가 있다.
이 다대다 매핑을 위해 생성된 테이블은 매핑정보만 저장하며 추가적인 정보를 저장할 수 없다.
그리고 중간 테이블이 숨겨져있어서 생각지 못한 쿼리가 나간다.
다대다 한계의 극복
연결 테이블을 Entity로 만들어주면 깔끔하게 해결된다.
즉, 중간에 숨겨진 매핑용 테이블을 Entity로 만들어서 중간 단계 테이블로 만들어주면 된다.
Reference
인프런 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편