1. 제1 정규형 : 모든 속성은 반드시 하나의 값을 가져야 한다.
1) 다중 값을 가지는 경우
하나의 속성에는 하나의 값을 가져야 하고 다중 값이 들어갈 경우에는 고객 연락처라는 엔티티를 추가하여 따로 관리하자.
2) 다른 유형의 중복 데이터를 가지는 경우
중복 데이터를 분리하여 주문 상세라는 엔티티를 만들어 다른 유형의 중복 데이터 발생하지 않게 한다.
제2 정규형 : 엔티티의 일반 속성은 주 식별자 전체에 종속적이어야 한다.
여기서는 상품명이 식별자 전체가 아닌 상품 번호에만 종속되어있는 부분 종속에 해당한다. 상품명을 변경해 주어야 할 때 주문 상세에 상품명을 모두 변경해야 하고 많이 팔린 상품을 수정하는데 부하가 크게 증가한다 따라서 나누어 줘야 한다.
상품 엔티티를 추가해서 주문 상세 엔티티의 부분 종속성을 다음과 같이 제거한다.
제3 정규형 : 엔티티의 일반 속성 간에는 서로 종속적이지 않다.
바로 위 그림에서 주문 엔티티에 고객번호는 주문번호에 종속적이고 고객명은 고객번호에 종속적이다. 즉, 고객명이 주문번호에 종속적이다. 이것을 이행적 종속이라고 하고 이행적 종속을 제거하는 것이 제3 정규형이다.
고객의 이름이 바뀌면 주문 엔티티의 고객명을 전붕 갱신해야 한다. 이는 주문과 연관 없는 트랜잭션이다.
따라서 아래 그림과 같이 고객의 엔티티를 따로 분리해주어야 한다.
4. 반 정규화와 성능
정규화는 데이터의 중복을 최소화했다면 반정 규화는 성능을 위해 데이터의 중복을 허용하는 것이다.
조회 성능을 향상시킬 수 있을지라도 입력, 수정, 삭제 성능은 저하될 수 있다.
1) 반정규화를 적용한 모델에서 성능이 향상될 수 있는 경우
고객 편의를 위해 주문서 작성 시 최근 결제 정보를 미리 세팅하여 보여줄 때
고객번호가 1234인 고객의 주문정보를 결제 테이블과 조인하여 가져온 후 신용카드 결제정보를 결제 일시로 내림차순 정렬해 최근 1건의 결제수단 번호를 가져온다. 이때 고객 1234의 주문내역이 많을수록 성능이 나빠지는 문제가 발생할 수 있다. 이는 결제 앤티 티에 고객번호 속성을 반정 규화 함으로써 조인에 대한 성능 부하를 개선할 수 있다.
2) 반정규화를 적용한 모델에서 성능이 저하될 수 있는 경우
주문과 배송의 관계에서 고객이 주문한 내역에 대한 배송정보 조회하는 기능을 구현할 때 고객이 주문한 주문정보가 필요하고 주문한 상품의 송장번호가 필요하다. 송장번호란 택배사로부터 전달받은 번호로 배송 엔티티에 들어간다. 즉, 주문 엔티티와 배송 엔티티를 조인해야 한다. 그런데 조인은 성능이 느려질 수 있기 때문에 반정 규화를 통해 주문 엔티티에 송장번호를 넣는다고 가정했을 때 불필요한 UPDATE로직이 들어간다.
고객이 주문할 시점에는 송장번호가 null이고 배송준비가 완료되어야 송장번호를 갱신(UPDATE)할 수 있기 때문이다. 반정 규화 하기 전에는 UPDATE로직이 추가로 필요하지 않았지만 불필요한 로직이 생긴 것이다.
'CS > DataBase' 카테고리의 다른 글
Redis (0) | 2021.08.11 |
---|---|
MySQL 인덱스(Index) & 파티션Partition & Full-Text Search (0) | 2021.08.09 |
DB관련 익셉션 변환 처리 및 트랜잭션 처리 (0) | 2021.08.05 |
Database Design (0) | 2021.07.22 |
ShoppingMall ERD (0) | 2021.07.02 |