백엔드의 꽃(?) 데이터 베이스 정규화와 Spring boot으로 정규화 구현에 대해

2023. 3. 27. 15:28·Backend/Spring
반응형

내가 깃허브에 올린 데이터베이스 스키마를 이용해서 설명하겠다.

 

우선 매핑은 서로 연관되는 항목의 수에 따라 일대일 매핑, 일대다 매핑, 다대일 매핑, 다대다 매핑으로 나눌 수 있으며, 

방향성에 따라 단방향매핑과 양방향매핑으로 나눌 수 있다.

 

쉽게 이해할 수 있게 하나씩 설명을 하겠다.

 

1. 일대다 매핑
스키마에서 Member와 Order은 일대다 매핑인 것을 볼 수 있다.(한 사람이 여러개의 주문을 할 수 있기 때문에)

 

2. 일대일 매핑
Order와 Delivery는 일대일 매핑이다.(주문 한개당 한 개의 배송을 하기 때문)

 

3. 다대일 매핑
Order와 Member의 관계(여러 주문을 한 사람이 할 수 있다)

 

4. 다대다 매핑
Order와 Item의 관계(여러개의 주문에 다양한 물건들을 구매할 수 있다)
*다대다 매핑은 권장하지 않으므로 중간 엔티티를 만들어서 일대다, 다대일 관계로 사용했다.


이렇게 말만 들으면 쉬운 것 같지만 실제 프로젝트를 할 때 가장 고민되는 부분이 데이터베이스 정규화 과정이다.

 

단방향 매핑과 양방향 매핑이란?

데이터베이스 테이블은 외래 키 하나로 양쪽 테이블 조인이 가능합니다.

즉 굳이 단방향이나 양방향으로 나눌 필요가 없다는 것입니다.

그럼에도 불구하고 나누는 이유는 객체는 참조용 필드가 있는 객체만 다른 객체를 참조하는 것이 가능하기 때문입니다.

두 객체 모두가 참조용 필드를 가지고 참조를 하면 양방향 필드, 한쪽만 참조용 필드를 가지고 있으면 단방향 필드입니다.


코드와 함께 설명하겠습니다.

 

양방향 매핑

1. ManyToOne, OneToMany

1
2
3
4
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
 
Colored by Color Scripter
cs

Order 클래스에서 Member 객체를 ManyToOne(다대일 매핑)으로 관리한다.

이때 JoinColumn 어노테이션에 집중해야 한다. JoinColumn 어노테이션을 가지고 있는 클래스를 보통 주인이라고 하며, 

상대 테이블을 Join해주는 역할을 한다. Order클래스는 연관관계의 주인이므로 외래키(대상 테이블의 PK)를 가진다.

 

1
2
3
4
5
6
@Id
@GeneratedValue
@Column(name = "member_id")
private Long id;    
@OneToMany(mappedBy = "member") // order 테이블에 있는 Member 필드에 의해 나는 mapping 된거야
private List<Order> orders = new ArrayList<>();
cs

mappedBy는 연관관계의 주인이 아닌 클래스에서 사용하는데 위 코드는 Member클래스이다.

Member클래스와 Order클래스의 연관관계에서는 Order 클래스가 주인이므로 Member 클래스에는 mappedBy가 있어야 한다. mappedBy(member)를 해서 Order 클래스에 있는 Member 필드에 의해 매핑된 것을 알 수가 있다.

 

양방향 매핑에서는 연관관계의 주인 쪽에 JoinColumn이 있고 주인이 아닌 쪽에 mappedBy가 있다.(일대다 매핑이면 보통 "다"쪽이 주인이다)

 

2. OneToOne

1
2
3
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) // FetchType 알아보기
@JoinColumn(name = "delivery_id")
private Delivery delivery;
Colored by Color Scripter
cs

OneToOne은 1대1관계이다. Order과 Delivery는 앞서 말했듯이 일대일 관계이다.

일대다 다대일 관계에서는 "다"쪽이 연관관계의 주인인데 일대일 관계는 설계자가 설계하기 나름이다.

나는 Order과 Delivery에서 Order를 연관관계의 주인으로 설정했다.

3번째 줄의 JoinColumn(name = "delivery_id")를 통해 Order에서 외래키(Delivery의 PK인 delivery_id)를 가질 수 있게 해 준다.

 

1
2
3
4
5
6
7
@Id
@GeneratedValue
@Column(name = "delivery_id")
private Long id;
@JsonIgnore
@OneToOne(mappedBy = "delivery",fetch = FetchType.LAZY)
private Order order;
Colored by Color Scripter
cs

Delivery는 연관관계의 주인이 아님으로 mappedBy를 사용해서 Order클래스에 있는 delivery필드에 의해 매핑된 것을 말해준다.


단방향 매핑

단방향 매핑은 JoinColumn으로 연관관계의 주인만 참조용 필드를 가지고 있는 경우입니다.

ex) 연관관계의 주인만 JoinColumn을 하고 대상 테이블은 mappedBy를 하지 않는다.

 


@ManyToMany

실무에서 절대 사용하면 안 되는 것이다.

만약 사용하게 된다면 중간 엔티티를 만들어서 일대다, 다대일 관계로 사용해야 한다.

 

1
2
3
4
5
@ManyToMany
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id"))
private List<Item> items = new ArrayList<>();
cs

@JoinTable을 통해 두 테이블을 연결하는 별도의 테이블을 생성한다.

그리고 JoinColums, inverseJoinColumns를 통해 일다, 다대일 관계로 관리합니다.

joinColumns : 현재 Entity를 참조하는 FK
inverseColumns : 반대방향 Entity를 참조하는 FK


ToOne에 사용되는 fetchType은 다음 강의에서 설명하겠다 :)

 

 

 

반응형
'Backend/Spring' 카테고리의 다른 글
  • [Spring-boot] Redis를 활용한 RefreshToken 저장 및 조회
  • [POSTMAN] 쿠키 설정 및 확인하기
  • Debugging를 간단히 해주는 Log에 대하여 (slf4j)
  • Intellij Lomlok을 사용할때 해야하는 설정들
코딩하는_대학생
코딩하는_대학생
Java Developer, Open Source Enthusiast, Proud Son
  • 코딩하는_대학생
    코딩하는 대학생에서 개발자까지
    코딩하는_대학생
  • 전체
    오늘
    어제
    • 분류 전체보기 (216)
      • 코딩하는 대학생의 책 추천 (8)
        • 클린코드 (5)
        • 헤드퍼스트 디자인패턴 (3)
      • Backend (6)
        • Spring (14)
        • AWS (3)
        • 회고 (4)
        • Redis (5)
        • 다양한 시각에서 바라본 백엔드 (3)
      • Python (35)
        • 개념 및 정리 (15)
        • 백준 문제풀이 (20)
      • JAVA (17)
        • 개념 및 정리 (14)
        • 백준 문제풀이 (2)
      • 왜? (7)
      • C언어 (42)
        • 개념 및 정리 (9)
        • 백준 문제풀이 (32)
      • 개인 공부 (27)
        • 대학 수학 (5)
        • 대학 영어 (10)
        • 시계열데이터 처리 및 분석 (5)
        • 컴퓨터 네트워크 (6)
        • 운영체제 (1)
      • 솔직 리뷰 (23)
        • 꿀팁 (6)
        • IT기기 (1)
        • 국내 여행 (7)
        • 맛집 (2)
        • 알바 리뷰 (2)
      • 대외활동 (17)
        • 체리피우미 3기 (4)
        • 꿀잠이들 6기 (13)
      • 음식 평가 (1)
      • 일상 & 근황 (2)
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩하는_대학생
백엔드의 꽃(?) 데이터 베이스 정규화와 Spring boot으로 정규화 구현에 대해
상단으로

티스토리툴바