1. 연관 관계 매핑 시 고려사항 3가지
- 다중성
- 다대일(@ManyToOne), 일대다(@OneToMany), 일대일(@OneToOne), 다대다(@ManyToMany)
- @ManyToMany는 실무에서 절대 사용하지 말것.
- 단방향, 양방향
- 테이블은 방향이 없지만, 객체는 방향이 있다(참조).
- 연관 관계의 주인
- 테이블은 외래 키 하나로 두 테이블이 연관관계를 맺지만 객체는 참조가 2군데
- 외래 키를 관리하는 참조가 연관 관계의 주인
2. 여러 시나리오
앞이 연관 관계의 주인이다.
- N : 1 : 단방향(가장 많이 사용한다.), 양방향
- N쪽에 외래 키가 가야한다. => 연관 관계의 주인은 N쪽 (이쪽에 참조를 걸 것)
- 1 : N
- 단방향 : 객체 입장에서는 이런 설계가 나올 수 있는데, DB입장에서는 초큼...
- DB에서는 N쪽에 FK가 들어가긴 함
- 어쩔 수 없이 update 쿼리가 한 번 더 들어감 (성능상 손해긴 함)
- 실무에서는 추천 안함. 스펙상 제공되기에 설명함.
- 심각한 문제 : 코드상으로 보이는게 Team 손댔는데 Member쪽에 update가 보임
내 외래키가 아닌 다른 외래키가 필요하기에 update하는 것. - 그렇기에 이 방향보다는 N : 1 양방향 매핑 전략 추천.
- 심각한 문제 : 코드상으로 보이는게 Team 손댔는데 Member쪽에 update가 보임
- @JoinColumn 안쓰면 JOIN Table이라는 중간 테이블을 만들어서 하는 식이라 성능상 문제.
- 양방향 : 아래와 같은 방식으로 어거지로 사용하는 것.
- 읽기 전용 필드로 사용하는 것
- 이것도 N : 1 양방향 매핑 사용하자.
- 단방향 : 객체 입장에서는 이런 설계가 나올 수 있는데, DB입장에서는 초큼...
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)
Team team;
- 1 : 1
- 주 테이블이나 대상 테이블 중에 외래 키 선택 가능 (기준이 필요하지)
- 외래키에 DB unique 제약조건 추가
- 주 테이블에 외래 키 단방향
- 주 테이블에 외래 키 양방향
- 다대일 양방향 매핑처럼 외래 키가 있는 곳이 연관 관계의 주인
- 반대편에 @OneToOne(mappedBy = "team") 처럼 적어야함.
- 개발자의 입장에서, 주 테이블을(Member를) 자주 조회한다면 Member한테 Locker 외래키가 있는 게
성능상의 이점, 여럿 장점이 있다. 객체 지향 개발자 선호
- 대상 테이블에 외래 키 단방향 : 지원 안됨
- 대상 테이블에 외래 키 양방향 : 위의 주 테이블 외래키 양방향과 동일.
- 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨
대상 테이블에 값이 있는지 없는지 조회하려면, 주 테이블만 조회하지 않음
어차피 대상 테이블을 확인해야 한다.
- 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨
- 1 : 1 양방향의 경우, 정답은 없는데...
- 하나의 회원이 여러개의 Locker를 가질 수 있는 비즈니스 룰이 생긴다면???
- Locker에 외래키가 있었다면 변화가 별로 없다.
- Member에 외래키가 있었다면 변화가 많다.
- 하나의 Locker가 여러개의 회원을 가질 수 있다면??? 반대의 선택이 맞다.
- 하나의 회원이 여러개의 Locker를 가질 수 있는 비즈니스 룰이 생긴다면???
- M : N
- RDBMS는 정규화된 테이블 2개로 M:N 관계 표현 불가능, 테이블 추가해서 1:N, M:1 관계로 풀어내야 함
- 객체는 또 M:N이 되긴 해 ➡️ 객체는 컬렉션 사용해서 객체 2개로 가능 (양쪽에 List넣는 것)
- @ManyToMany, @JoinTable로 연결 테이블
- M : N 매핑의 한계
- 편리해보이지만, 실무에서 사용 X
- 연결 테이블은 단순 연결이라 PK, FK들만 있다. / 주문 시간, 수량 데이터는 없다.
- 대안?
- 연결 테이블 용 Entity를 새로 만드는 것
- M : N 관계라고 했을 때 MN짜리 Table을 만들어서 사이에 둔다.
- M : MN : N 관계로 바꾼뒤 앞의 두 개는 1:N의 관계, 뒤의 두 개는 M:1의 관계가 된다.
- 연관 관계의 주인은 MN에 전부 다 집어넣는 것.
- PK, FK의 두 가지 방식
- 가운데 PK 하나를 두고, FK 2개를 집어넣는 방식 (PK가 의미 없는 값이 되는 경우)
모든 테이블에 GeneratedValue를 통해 id를 생성하는 것. - (PK, FK), (PK, FK) 처럼 PK가 의미 있는 값이 되는 방식
- 가운데 PK 하나를 두고, FK 2개를 집어넣는 방식 (PK가 의미 없는 값이 되는 경우)
'정보 > Database' 카테고리의 다른 글
프록시, JPA 최적화 (0) | 2024.11.17 |
---|---|
연관 관계 Mapping (3) (0) | 2024.11.17 |
연관 관계 Mapping (1) (0) | 2024.11.15 |
Entity Mapping (3) | 2024.11.15 |
JPA Persistence Context 는 Git과 흡사하다 (0) | 2024.11.13 |