2. 데이터 모델과 SQL
01. 정규화(Normalization)
데이터 정합성(데이터의 정확성과 일관성을 유지하고 보장)을 위해 엔터티를 작은 단위로 분리하는 과정.
입력, 수정, 삭제 성능은 일반적으로 향상된다고 볼 수 있다.
정규화를 하게 되면 엔터티가 계속 증가하므로 JOIN으로 인한 조회 성능 저하가 발생할 수 있다.
1) 제1정규형
모든 속성은 반드시 하나의 값만 가져야 한다.
하나의 속성에 여러 속성값을 갖는 경우.
단점 : 불필요한 split 사용, 데이터 추출의 번거로움
예시)
⬇️ 원본
이름 나이 별명 내동생 8 꿀돼지, 두꺼비, 왕자님
⬇️ 제1정규형화
이름 나이 내동생 8 이름 별명 내동생 꿀돼지 내동생 두꺼비 내동생 왕자님 유사한 속성이 반복되는 경우
단점 : 계속해서 늘어나는 속성 추가, 공간의 낭비 발생 여지
예시)
⬇️ 원본
이름 나이 학원1 학원2 학원3 내동생 8 피아노학원 영어학원 태권도
⬇️ 제1정규형화
이름 나이 내동생 8 이름 학원 내동생 피아노학원 내동생 영어학원 내동생 태권도
2) 제2정규형
엔터티의 모든 일반속성은 반드시 모든 주식별자에 종속되어야 한다. 주식별자가 단일식별자가 아닌 복합식별자인 경우 일반속성이 주식별자의 일부에만 종속될 수 있다. 이때 데이터 이상 현상이 발생할 수 있다.
주문번호(PK) | 상품코드(PK) | 수량 | 상품명 |
---|---|---|---|
2023082801 | A001 | 1 | 아메리카노 |
2023082801 | A002 | 2 | 바닐라라떼 |
2023082802 | A001 | 1 | 아메리카노 |
🔺주문번호와 상품코드가 주식별자인 경우 |
위의 경우 주문번호가 없는 상품은 입력 할 수 없는 입력 이상 현상, 상품명이 변경될 경우 해당 상품명에 대한 데이터가 모두 변경되어야 하는 수정 이상 현상이 발생한다.
⬇️ 제2정규형화
주문번호(PK) | 상품코드(PK) | 수량
:---:|:---:|:---:
2023082801 | A001 | 1
2023082801 | A002 | 2
2023082802 | A001 | 1
상품코드(PK) | 상품명 |
---|---|
A001 | 아메리카노 |
A002 | 바닐라라떼 |
3) 제3정규형
주식별자가 아닌 모든 속성 간에는 서로 종속될 수 없다.
상품코드(PK) | 상품명 | 제조사코드 | 제조사명 |
---|---|---|---|
A001 | 신라면 | ABC | 농심 |
A002 | 진라면 메운맛 | AAA | 오뚜기 |
A002 | 진라면 순한맛 | AAA | 오뚜기 |
일반속성인 제조사명이 다른 일반속성인 제조사코드에 종속되어있다.
⬇️ 제3정규형화
상품코드(PK) | 상품명 | 제조사코드
:---:|:---:|:---:
A001 | 신라면 | ABC
A002 | 진라면 메운맛 | AAA
A002 | 진라면 순한맛 | AAA
제조사코드 | 제조사명 |
---|---|
ABC | 농심 |
AAA | 오뚜기 |
이행 함수 종속성을 제거한다.
4) 주의사항
지나친 정규화는 오히려 성능저하를 일으킬 수 있다.
특정 데이터의 연관 데이터를 조회하기 위해 여러 번의 JOIN을 해야 할 수도 있다. 이때 각 엔터티 간의 관계를 생성하여 성능을 개선할 수 있다.
02. 반정규화(De-Normalization)
데이터의 조회 성능을 향상시키기 위해 데이터의 중복을 허용하거나 데이터를 그룹핑하는 과정. 조회 성능은 향상될 수 있으나 입력, 수정, 삭제 성능은 저하될 수 있으며 데이터 정합성 이슈가 발생할 수 있다. 반정규화 과정은 정규화가 끝난 후 성능상 이슈가 있을때 고려한다.
1) 테이블 반정규화
테이블 병합
업무 프로세스상 JOIN이 필요한 경우가 많아 테이블을 통합하는 것이 성능 측면에서 유리한 경우 고려한다. 1:M 관계 테이블 병합의 경우 1쪽에 해당하는 엔터티의 속성 개수가 많으면 병합했을 경우 중복 데이터가 많아지므로 테이블 병합에 적절하지 못하다.
(테이블의 관계가 강결합이어서 같이 조회되는 경우가 대부분일 경우 비정규화를 고려한다.)
1:1 관계 테이블 병합
회원정보 + 회원개인정보 => 회원정보
1:M 관계 테이블 병합
주문정보 + 주문상품상세정보 => 주문정보
슈퍼 서브 타입 테이블 병합
테이블 분할
테이블 수직 분할(속성 분할)
엔터티의 일부 속성을 별도의 엔터티로 분할(1:1 관계 성립)
수직 분할 시 한 개의 블록에 더 많은 인스턴스를 저장할 수 있게 된다.
(자주 사용하는 속성이 아니거나 대부분의 인스턴스가 해당 속성값을 NULL로 갖고 있을 때 고려한다.)
월/일/기념일 => 월/일 기념일
테이블 수평 분할(인스턴스 분할, 파티셔닝)
엔터티의 인스턴스를 특정 기준으로 별도의 엔터티로 분할
테이블의 수평 분할을 할 경우 관계가 없는 다수의 테이블이 생성된다.
주문 => 2023주문, 2022주문
테이블 추가
중복 테이블 추가
데이터의 중복을 감안하더라도 성능상 반드시 필요하다고 판단되는 경우 별도의 엔터티를 추가한다.
통계 테이블 추가
통계치를 미리 계산하여 저장
이력 테이블 추가
이력에 대한 데이터를 관리
부분 테이블 추가
2) 컬럼 반정규화
중복 컬럼 추가
업무 프로세스상 JOIN이 필요한 경우가 많아 컬럼을 추가하는 것이 성능 측면에서 유리할 경우 고려한다.
파생 컬럼 추가
프로세스 수행 시 부하가 염려되는 계산값을 미리 컬럼으로 추가하여 보관하는 방식으로 상품의 재고나 프로모션 적용 할인가 등이 이에 해당할 수 있다.
이력 테이블 컬럼 추가
대량의 이력 테이블을 조회할 때 속도가 느려질 것을 대비하여 조회 기준이 될 것으로 판단되는 컬럼을 미리 추가해 놓는 방식이다. 최신 데이터 여부 등이 이에 해당할 수 있다.
3) 관계 반정규화(중복관계 추가)
업무 프로세스상 JOIN이 필요한 경우가 많아 중복 관계를 추가하는 것이 성능 측면에서 유리할 경우 고련한다. 데이터의 무결성을 깨뜨릴 위험성 없이 데이터 처리 성능을 향상시킬 수 있는 기법이다.
03. 트랜잭션(Transaction)
데이터를 조작하기 위한 하나의 논리적인 작업 단위.
- 게임 출석 이벤트 미션 달성
- 게임 접속
- 게임 메인 페이지
- 게임 출석 API 호출
- 출석 이력 저장
- 저장 성공
- 이벤트 성공 아이템 제공
- 제공 성공
- API 호출 응답
위와 같은 작업의 경우 아이템 제공에 실패 할 경우 아이템 제공 실패, 출석 이력 저장도 롤백되어야 한다.
04. NULL
NULL은 존재하지 않음, 값이 없음을 의미한다. 데이터가 입력되지 않아 NULL값이 된 것이다.
- 가로연산(동일한 인스턴스 내 계산) : NULL이 포함되어 있는 경우 결과는 NULL이 된다.
- 세로연산(다른 인스턴스와 계산) : NULL을 제외하고 계산한다.
NULL과의 비교 연산 결과는 늘 NULL이다.
tip! 성능 데이터 모델링
성능 데이터 모델링은 데이터베이스의 성능을 향상시키기 위해 설계 단계부터 성능과 관련된 사항들이 모델링에 반영될 수 있다.
tip! 성능 데이터 모델링의 순서
- 데이터 모델에 맞게 정규화를 수행한다.
- 데이터베이스의 용량 및 트랜잭션 유형을 파악하여 성능 저하를 일으키는 부분이 없는지 검토한다.
- 용량과 트랜잭션 유형에 맞게 반정규화를 수행한다.
- 성능 향상을 위한 이력모델의 조정, PK/FK 조정, 슈퍼/서브타입 조정 등을 수행한다.
- 데이터 모델의 성능을 검증한다.
'SQLD' 카테고리의 다른 글
03. SQL 기본 (0) | 2023.08.30 |
---|---|
01. 데이터 모델링의 이해 (0) | 2023.08.24 |