SQLD 공부 PART 1 - CH2. 데이터 모델과 SQL
SQLD - Week 2 - Part1 - CH2. 데이터 모델과 SQL
- 책 <2023 유선배 SQL개발자(SQLD) 과외노트>로 기본 이론 단권화
- 유튜브 <홍쌤의 데이터랩> 참고
- 참고 : 블로그 harinnnn
1. 성능 데이터 모델링
- 데이터베이스의 성능을 향상시키기 위해 설계단계부터 성능과 관련된 사항이 모델링에 반영될수 있도록 하는것
- 방법으로 정규화, 반정규화, 테이블통합, 테이블 분할 등이 있음
순서
- 데이터 모델에 맞게 정규화 수행
- 데이터 베이스의 용량/트랜잭션 유형을 파악해서 성능저하를 일으키는 부분이 없는지 검토
- 용량/트랜잭션 유형에 맞게 반정규화 수행
- 이력모델의 조정, PK/FK 조정, 슈퍼/서브타입 조정 등을 수행 -> 성능향상
- 데이터모델의 성능 검증
2. 성능데이터 모델링 방법
정규화
- 논리 데이터 모델의 일관성을 확보하고 중복을 제거해서 속성들익 가장 적절한 엔터티에 배치하는것
- 중복데이터를 허용하지 않는 방식으로 테이블을 설계하는 방식
- 데이터 정합성(데이터의 정확성/일관성을 유지&보장)을 위해 엔터티를 작은 단위로 분리하는 과정
- 함수 종속성을 고려해 이상 현상이 생기지 않도록 테이블 분할(반정규화X)
- 지나친 정규화는 성능저하를 일으킴
함수 종속성 Functional Dependency
- 함수처럼 어떠한 값을 통해 종속 관계에 있는 다른 값을 유일하게 결정할수 있다
- e.g. 테이블에 [생일], [나이]라는 컬럼이 존재할때
- [나이]는 [생일]에 종속한다 : 생일을 알고 있으면 나이를 참조하지 않아도 나이를 결정할수 있음
- e.g. 테이블에 [생일], [나이]라는 컬럼이 존재할때
- 데이터베이스 설계단계에서 함수 종속 관계를 찾으면 중복된 데이터를 줄일수 있음
함수 종속의 성질(암스트롱의 공리 Armstrong’s axioms)
- augmentation : X → Y이면, XZ → YZ
- transitivity : X → Y이고 Y → Z이면, X → Z
- reflexivity : Y $\sub$ X, X → Y
- self-determination : X → X (자기 자신은 자신에 의해 함수 종속적이다)
- union : X → Y이고 X → Z이면, X → YZ
- decomposition : X → YZ이면, X → Y이고 X → Z
정규화 단계
- 제1정규형(1 Normal Form: 1NF) : 엔터티의 모든 속성은 반드시 하나의 값만 가져야 한다
- 유사한 속성이 반복되면 -> 1차 정규화!
- 테이블의 컬럼은 하나의 값(원자값)을 갖도록 테이블 분해
- 제2정규형(2 Normal Form: 2NF) : 엔터티의 모든 속성은 반드시 모든 주식별자에 종속되어야한다
- 어떤 속성이 일부 주식별자에만 종속되어있다면 -> 2차 정규화!
- 부분 함수 종속성 제거 : 완전 함수 종속 만족
- 릴레이션에서 종속자가 기본키가 아닌 다른 속성에 종속되거나, 기본키가 여러 속성으로 되어있을때
- 기본키를 구성하는 속성 중 일부만 종속된 경우
- 릴레이션에서 종속자가 기본키가 아닌 다른 속성에 종속되거나, 기본키가 여러 속성으로 되어있을때
- 제3정규형(3 Normal Form; 3NF) : 주식별자가 아닌 모든 속성간에는 서로 종속될수 없다
- 2차 정규화를 진행한 테이블에 이행적 종속이 없도록 테이블을 분해하는 것
- 이행적 종속 : A → B, B → C 성립할때 A → C가 성립하는 것
- 이행함수 종속성 제거
- 속성간에 종속되어있다면 -> 3차 정규화!
- 기본키가 있는데 일반속성이 일반속성을 결정하는 경우
- 2차 정규화를 진행한 테이블에 이행적 종속이 없도록 테이블을 분해하는 것
- 제4정규형 : 다중값 종속성 제거 -> 4차 정규화!
반정규화
- 데이터 조회 성능 향상을 위해 데이터 중복을 허용/데이터를 그룹핑 하는 과정
- 정규화 작업 이후에 수행
- 정규화 작업 이후에 성능상의 이슈가 있으면 실행!
- 데이터 무결성 저해 가능성 있음 : 디스크 I/O량 감소, 긴 경로의 조인으로 인한 성능저하 해결
- 조회(SELECT) 속도는 향상시키지만, 데이터모델의 유연성은 낮아짐
반정규화 조건
- 여러번의 JOIN으로 성능이 저하되는 것을 방지하기 위해
- 모델링의 마지막 단계에서 성능을 향상시키기 위해
- 런타임에 컬럼 계산으로 인한 속도 저하가 우려될 경우
- 다량의 범위를 자주 처리해야하는 경우
- 특정 범위의 데이터만 자주 처리하는 경우
- 요약/집계 정보가 자주 요구되는 경우
기법
- 테이블 반정규화
- 테이블 병합 : 업무 프로세스상 JOIN이 많을때
- 1:M 관계 테이블 병합 : 1쪽에 해당하는 엔터티 속성 개수가 많으면 중복데이터가 많아질수있음
- 슈퍼/서브타입 테이블 병합
- 테이블 분할
- 테이블 수직 분할 : 엔터티 일부 속성을 별도의 엔터티로 분할(1:1 관계 성립)
- 자주 사용하는 속성이 아니거나
- 대부분의 인스턴스가 해당 속성값을 NULL로 갖고있을떼
- e.g. 한 테이블에 속성 개수가 과도하게 많을경우 조회 성능 향상을 위해 수직분할 수행
- 자주 쓰이는 속성/아닌 속성
- 분할된 테이블은 1:1 관계 성립
- e.g. 한 테이블에 속성 개수가 과도하게 많을경우 조회 성능 향상을 위해 수직분할 수행
- 테이블 수평 분할 : 엔터티의 인스턴스를 특정 기준으로 별도의 엔터티로 분할(파티셔닝)
- 주로 ‘기간’을 기준으로 분할
- 관계없는 다수의 테이블이 생성될수 있음
- 테이블 수직 분할 : 엔터티 일부 속성을 별도의 엔터티로 분할(1:1 관계 성립)
- 테이블 추가
- 중복 테이블 추가 : 중복을 감안하더라도 성능상 필요한 경우 별도 엔터티 추가
- 통계 테이블 추가
- e.g. 주문 데이터를 이용 -> 월매출 테이블에 통계치를 미리 계산해서 저장
- 이력 테이블 추가
- e.g. 상품 이력 테이블 -> 과거의 상품가격에 대한 데이터 관리
- 부분 테이블 추가
- e.g. 회원 대상 메일 발송건이 다량 생기는 경우 -> 메일 발송에 필요한 정보만 부분 테이블[^1]로 생성
- 테이블 병합 : 업무 프로세스상 JOIN이 많을때
- 컬럼 반정규화
- 중복 컬럼 추가 : 업무 프로세스상 JOIN이 많이 필요한 경우
- 파생 컬럼 추가 : 프로세스 수행시 부하가 염려되는 계산값을 따로 컬럼에 추가해서 보관
- e.g. 상품 재고, 프로모션 적용 할인가
- 이력 테이블 컬럼 추가 : 대량의 이력 테이블을 조회할때 속도 저하를 대비, 조회 기준이 되는 컬럼을 미리 추가
- e.g. 최신 데이터 여부
- 관계 반정규화 - 중복관계추가
- 업무 프로세스상 JOIN이 많이 필요한 경우 중복관계를 추가하는게 성능 측면에서 유리한 경우
- 데이터 무결성을 깨뜨릴 위험없이 데이터 처리 성능을 향상시킬수 있음
3. 트랜잭션 Transaction
- 데이터를 조작하기 위한 하나의 논리적인 작업 단위
- 하나의 연속적인 업무 단위
- 트랜잭션에 의한 관계 -> 필수적인 관계 형태를 가짐
- 하나의 트랜잭션에는 여러 SELECT, INSERT, DELETE, UPDATE가 포함될수 있음
- e.g. 1) 온라인에서 퀴즈의 정답을 맞히면 쿠폰을 즉시 발행해주는 이벤트 - 쿠폰은 선착순 100명에게만 지급
- 트랜잭션
- 이벤트 응모 이력을 저장한다
- 쿠폰을 발행한다
- 트랜잭션
- e.g. 2) A가 B에게 100만원을 계좌이체
- 1) A 잔액이 100만원 이상인지 확인
- 2) 이상이면, A 잔액을 -100 UPDATE
- 3) B 잔액에 +100 UPDATE
- 2,3번이 동시에 수행되어야함(모두 성공/모두 취소) -> 트랜잭션
4. NULL
- 값이 없음 = 존재하지않음 = 아직 정해지지 않은 값
- COL = NULL : False(무조건)
- NULL은
=
으로 확인X -
IS NULL
/IS NOT NULL
로 확인
- NULL은
특징
- NULL이 있는 경우
- 가로연산 : NULL
- NULL을 치환후 계산
SELECT ENAME, SAL, COMM, SAL + NVL(COMM, 0) FROM EMP;
- 세로연산 : 다른 인스턴스의 데이터와 연산할때 NULL값 제외
- 집계함수에서 해당
- e.g. SUM() : 컬럼값이 NULL인 Row 제외하고 합계 계산
- 가로연산 : NULL
- 정렬이 되는 컬럼에서 NULL은 최댓값(Oracle/ SQL Server: 최솟값) : 오름차순일 경우 맨 마지막에 위치