728x90
1: N 관계에서 외래 키의 주인과 위치
1: N 관계에서는 N 쪽의 테이블이 외래 키의 주인입니다. 즉, 외래 키는 N 쪽의 테이블에 위치합니다. 만약 1쪽이 외래 키의 주인이어도 1의 테이블에 외래 키가 생길 이유가 없습니다.
- 1대N 관계에서 1쪽이 외래 키의 주인일 때
- 1쪽의 테이블에 외래 키 컬럼이 생기는 것은
일반적이지 않습니다.- 외래 키는 보통 N쪽의 테이블에 위치합니다.
- 실제로 데이터베이스에서는 N쪽의 테이블이 외래 키를 소유하고 있으며, 외래 키가 N쪽의 테이블에 위치하게 됩니다.
- 만약 1쪽이 외래 키의 주인이라면, 1쪽의 테이블에
외래 키 컬럼이 생성될 필요는 없으므로 추가적인 UPDATE 쿼리가 발생할 수 있습니다.- 이는 외래 키의 위치와 관리가
1쪽이 아닌 N쪽에서 이루어지기 때문입니다.
- 이는 외래 키의 위치와 관리가
- 1쪽의 테이블에 외래 키 컬럼이 생기는 것은
1(음식): N(고객) 관계
음식(Food) 엔티티
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToMany
@JoinColumn(name = "food_id") // users 테이블에 food_id 컬럼
private List<User> userList = new ArrayList<>();
}
고객(User) 엔티티
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
음식(Food)과 고객(User) 엔티티에서 외래 키를 관리하는 주인은 @JoinColumn 어노테이션을 사용한 Food 엔티티로 설정됩니다.
그러나 실제로 외래 키 컬럼은 User 엔티티의 테이블에 위치합니다.
따라서, 데이터베이스에서 외래 키를 가진 User 테이블에서 추가적인 UPDATE 쿼리가 발생할 수 있습니다.
테스트 해보기
@Test
@Rollback(value = false)
@DisplayName("1대N 단방향 테스트")
void test1() {
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
Food food = new Food();
food.setName("후라이드 치킨");
food.setPrice(15000);
food.getUserList().add(user); // 외래 키(연관 관계) 설정
food.getUserList().add(user2); // 외래 키(연관 관계) 설정
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
// 추가적인 UPDATE 쿼리 발생을 확인할 수 있습니다.
}
위와 같이 insert문과 추가적인 update문이 실행한 것을 확인할 수 있습니다.
이는 외래 키(FK)의 주인만이 FK를 등록, 수정, 삭제할 수 있기 때문입니다. 그러나 FK의 주인이 관리하는 FK가 다른 테이블에 위치하고 있는 경우, 추가 작업이 발생할 수 있습니다.
구체적으로, User를 INSERT할 때 FK도 함께 설정하고 싶지만, User 엔티티는 외래 키의 주인이 아니므로 FK를 직접 등록할 수 없습니다.
따라서, User가 삽입된 후, 외래 키의 주인인 Food 엔티티가 User 테이블에 대해 UPDATE 쿼리를 실행하여 FK를 등록(수정)하는 방식으로 처리됩니다.
'TIL,일일 회고' 카테고리의 다른 글
[TIL, 일일 회고] 2024.08.26 - @Pattern 사용 (0) | 2024.08.26 |
---|---|
[TIL, 일일 회고] 2024.08.25 - 랜덤 시크릿 키 생성 방법 (openssl rand) (0) | 2024.08.25 |
[TIL, 일일회고] 2024.08.23 - JPA Entity 클래스 간의 참조: 의존성 주입이 아닌 FK 관계를 위한 설계 (0) | 2024.08.23 |
[TIL, 일일 회고] 2024.08.22 - assertThrows란 무엇일까❓: 예외를 테스트하는 효과적인 방법 (0) | 2024.08.22 |
[TIL, 일일 회고] 2024.08.21 - 비관적 락(Pessimistic Lock)으로도 업데이트 손실이 발생하는 이유 (0) | 2024.08.21 |