본문 바로가기
해피 코딩/Today I Learned

[TIL 7] 부족한 부분 채워 나가기

by happy-coding 2024. 8. 8.

Today I Learned

🔥 오늘은 알고리즘을 1문제 풀고, Chapter 1. 개인 프로젝트 진행 및 Entity 연관 관계를 공부하였다

[ 문제 ]

Chapter 1. 프로젝트 진행하며 느낀 점은 Entity 연관 관계에 대한 이해가 부족하다는 것이었다. 관계에 있어서 어느 쪽이 외래 키의 주인이며 @ManyToOne과 @OneToMany의 정확한 차이점을 구별하지 못하였고, 단방향과 양방향을 사용하는 이유에 대해서도 정확히 알지 못하고 있는 것 같다고 느꼈다

 

새로운 기술을 습득하며 앞으로 나아가는 것도 중요하지만, 지금처럼 스스로 공부가 부족하다고 느끼는 부분을 인지하고 부족한 부분을 채워나가는 것 또한 굉장히 중요하다고 느꼈다.
프로젝트를 통하여 더 늦기 전에 나에게 부족한 부분을 확인할 수 있어서 오히려 다행이라고 생각하며, 이번 기회를 계기로 Entity 연관 관계를 확실하게 정복해 나가야겠다 🚩 
📌 여기서는 @ManyToMany 에서의 중간테이블 사용 이유를 간단히 알아보고  @OneToOne에 대하여 다룰 예정이며, 다른 연관 관계에 대해서는 새로운 블로그에 작성할 계획이다

[ @ManyToMany 중간테이블 사용 이유 ]

예시를 위해 고객과 음식 테이블이 존재한다고 가정하고 설명하도록 하겠다.

 


[ 고객 테이블 ]

  • 한명의 고객은 음식을 여러개를 주문할 수 있습니다 / 고객과 음식은 1 대 N 관계입니다.
고객 입장에서 음식 주문하기
user table
id name food_id
1 병준 1
2 상우 3
3 용모 2
4 원철 3
5 병준 4
  • 표를 보면 알 수 있듯이 병준이가 중복되는 것을 볼 수 있다. Database에 값이 비효율적으로 저장되고 있다.

[ 음식 테이블 ]

  • 하나의 음식은 여러명의 고객에게 주문될 수 있습니다 / 음식과 고객은 1 대 N 관계입니다.
음식 입장에서 주문한 고객 정보 파악하기 / food 테이블
food table
id name price user_id
1 후라이드 치킨 20000 2
2 양념 치킨 23000 1
3 간장 치킨 25000 3
4 마늘 치킨 25000 2
5 양념 치킨 20000 4
  • 표를 보면 알 수 있듯이 양념치킨이 중복되는 것을 볼 수 있다. Database에 값이 비효율적으로 저장되고 있다.

[ 의문점 ]

  • 그렇다면 Database에 저장될 때, food 테이블 양념 치킨의 user_id 컬럼을 1,4 로 저장하면 되지 않을까?
food table
id name price user_id
1 양념 치킨 23000 1,4
  • 아쉽지만 user_id 컬럼에는 값이 하나밖에 들어갈 수 없다.

[ 해결 ]

  • 🤔 음.. 어떻게 해야 우리가 데이터를 Database에 효율적으로 저장하고 관리할 수 있을까?
  • 주문에 대한 정보를 기록할 orders 테이블을 사용하여 테이블들의 연관 관계를 해결합니다.  
고객
user table
id name
1 병준
2 상우
3 용모

 

음식
food table
id name price
1 후라이드 치킨 20000
2 양념 치킨 23000
3 간장 치킨 25000
4 마늘 치킨 25000

 

주문
orders table
id uesr_id food_id 주문일
1 1 1 2024-08-08
2 2 1 2024-08-08
3 3 4 2024-08-09
4 1 4 2024-08-10

 


[ 정리 ]

  • 고객 1명은 음식 N개를 주문할 수 있습니다 / 고객 : 음식 = 1 : N 관계
  • 음식 1개는 고객 N명에게 주문될 수 있습니다 /  음식 : 고객 = 1 : N 관계
  • 결론적으로 고객과 음식은 N : M 관계입니다 / 고객 : 음식 = N : M 관계
  • 이렇듯 N : M 관계인 테이블들의 연관 관계를 해결하기 위해 orders 테이블처럼 중간 테이블을 사용할 수 있습니다.

[ 1 대 1 관계 ]

예시를 위해 고객 Entity와 음식 Entity가 1 대 1 관계라 가정하여 관계를 맺어 설명하도록 하겠다.

 

  •  @OneToOne
    • @OneToOne 애너테이션은 1 대 1 관계를 맺어주는 역할을 합니다

[ 단방향 관계 ]

  • 외래 키의 주인 정하기
    • 중요❗ - 외래 키 주인만이 외래 키 를 등록, 수정, 삭제할 수 있으며, 주인이 아닌 쪽은 오직 외래 키 읽기만 가능합니다.

음식 Entity가 외래 키의 주인인 경우

음식과 고객의 1대 1 단방향 관계

  • 음식
    • @JoinColumn()은 외래 키의 주인이 활용하는 애너테이션입니다.
@Entity
@Table(name = "food")
public class Food {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String name;
  private double price;

  @OneToOne
  @JoinColumn(name = "user_id")
  private User user;
}

 

  • 고객
@Entity
@Table(name = "users")
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String name;
}

 


[ 양방향 관계 ]

  • 양방향 설정
    • 양방향 관계에서 외래 키의 주인을 지정해 줄 때 mappedBy 옵션을 사용합니다.
    • mappedBy의 속성값은 외래 키의 주인인 상대 Entity의 필드명을 의미합니다.
  • 양방향 설정 예시
    • mappedBy의 속성 값인 user는, 외래 키의 주인인 @JoinColumn의 필드 명인 user를 참조한다.
    • @JoinColumn()은 외래 키의 주인이 활용하는 애너테이션입니다.


음식과 고객의 1대 1 양방향 관계

  • 고객
@Entity
@Table(name = "users")
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String name;

  @OneToOne(mappedBy = "user")
  private Food food;
}

이로써 우리는 @ManyToMany 에서의 중간테이블 사용 이유를 간단히 알아보고,  @OneToOne 관계와 단방향과 양방향에 대하여 공부하였다. 최대한 쉽게 설명하려고 노력했으며 모두에게 큰 도움이 됐으면 좋겠다.

 

읽어주셔서 감사합니다 😊 

 

  • GitHub 커밋 확인하기

😺 GitHub: https://github.com/mad-cost/Sparta-EntityRelationship