AYSTORY
Part1 - Ch2. 데이터 모델과 SQL 본문
01) 정규화
- 데이터 정합성(데이터의 정확성과 일관성을 유지하고 보장)을 위해 엔터티를 작은 단위로 분리하는 과정
- 정규화를 할 경우 조회성능은 처리조건에 따라 향상되는 경우도 있고 저하되는 경우도 있지만 입력, 수정, 삭제 겅능은 일반적으로 향상
정규화
데이터의 무결성을 보장하기 위해 정규화를 수행한다.
1. 제1정규형
- 모든 속성은 반드시 하나의 값만 가져야 한다.
- 반복 그룹이 존재하면 안된다.
- 모든 행은 식별자로 완전하게 구분되어야 함.
- 반복되는 부분을 체크
- 반복되는 부분과 그렇지 않은 부분 분리
- 테이블을 나눈 후, 반복되는 행 삭제
원자값이 아닌 도메인을 분해
2. 제2정규형
- 엔터티의 모든 일반속성은 반드시 모든 주식별자에 종속되어야 한다.
- 전제: 먼저 제1정규형(1NF)을 만족해야 함.
- 정의: 모든 비주요 속성(non-prime attribute, 즉 후보키에 속하지 않는 속성)은 전체 기본키에 완전 함수 종속(Full Functional Dependency)되어야 함.
- 중요 포인트:
- 기본키가 단일 속성이면 자동으로 2NF 만족 → 문제는 복합키일 때 발생.
- 부분 함수 종속(Partial Dependency)이 있으면 위배됨.
- 부분 함수 종속이란? 복합키의 일부 속성에만 종속되는 경우.
- 2NF를 위반하면 → 해당 속성을 별도 테이블로 분리.
부분 함수 종속성을 제거
예제
아래 데이터 모델에서 회원 엔터티는 1차 정규화 대상이다.
∵ 회원 엔터티는 가족1, 가족2, 가족2 속성과 같이 유사한 속성의 반복 그룹 형태를 갖고 있으며 이는 1차 정규화 대상이 된다.
회원 (엔터티)
| 회원번호 |
| 아이디 이름 가족1 가족2 가족3 |
3. 제3정규형
- 주식별자가 아닌 모든 속성 간의 서로 종속될 수 없다.
-
모든 key가 아닌 컬럼(non-key)은 key 컬럼(속성)에 완전히 종속 되어야 함.
-
모든 non-key 컬럼은 key 컬럼(속성)에만 종속 되어야 함.
-
-
즉, key가 아닌 값에 주목하면 됨.
이행 함수 종속성을 제거
4. 주의사항
- 과유불급이란 말이 있듯이 적절한 정규화는 성능상 이롭지만 지나친 정규화는 오히려 성능 저하를 일으킬 수 있음.
- 회원의 배송상태를 조회하려면 여러 번의 JOIN을 해야 함.
- 회원 엔터티와 배송 엔터티 간의 관계를 생성하여 성능 개선
"테이블 분할: 함수 종속성을 고려하여 이상 현상이 생기지 않도록 테이블을 분할한다."
→ 함수의 종속성을 고려하여 이상 현상이 생기지 않도록 테이블을 분할하는 것은 정규화의 기법이다.
| 구분 | 부분 함수 종속성 | 이행 함수 종속성 |
| 정의 | 기본키의 일부에만 종속된 속성 | 기본키가 아닌 속성을 통해 종속된 속성 |
| 위반 정규형 | 제2정규형(2NF) 위반 | 제3정규형(3NF) 위반 |
| 해결 방법 | 부분 키가 아닌 속성은 분리 | 중간 매개 속성(비기본키)에 종속된 속성 분리 |
02) 반정규화
- 데이터의 조회 성능을 향상시키기 위해 데이터의 중복을 허용하거나 데이터를 그룹핑하는 과정
- 주의) 조회 성능은 향상될 수 있으나 입력, 수정, 삭제 성능은 저하될 수 있으며 데이터 정합성 이슈가 발생할 수 있다는 점
- 정규화가 끝난 후 거치는 과정 (정규화를 마친 후 성능상 이슈가 있을 때만 고려하는 것이 원칙)
반정규화
- 여러 번의 조인으로 인해 성능이 저하되는 것을 방지하기 위해 정규화 수행
- 모델링의 마지막 단계에서 성능을 향상시키는 목적으로 정규화 수행
- 런타임에 컬럼 계산으로 인한 속도 저하가 우려될 경우 정규화를 수행
1. 테이블 반정규화
| 테이블 병합 | 1:1 관계 테이블 병합 |
| 1:M 관계 테이블 병합 | |
| 슈퍼 서브 타입 테이블 병합 | |
| 테이블 분할 | 테이블 수직 분할(속성 분할) |
| 테이블 수평 분할(인스턴스 분할, 파티셔닝) | |
| 테이블 추가 | 중복 테이블 추가 |
| 통계 테이블 추가 | |
| 이력 테이블 추가 | |
| 부분 테이블 추가 |
1) 테이블 병합
- 업무 프로세스상 JOIN이 필요한 경우가 많아 테이블을 통합하는 것이 성능 측면에서 유리할 경우 고려.
- 1:M 관계 테이블 병합의 경우 1쪽에 해당하는 엔터티의 속성 개수가 많으면 병합했을 경우 중복 데이터가 많아지므로 테이블 병합에 적절X
예제
1:1 관계에서의 테이블 병합은 부작용이 클 수 있기 때문에 주의해야 함. (X)
→ 1:1 관계의 테이블 병합은 비교적 판단하기 수월하며 부작용도 적다.
1:M 관계에서의 테이블 병합은 1쪽에 해당하는 테이블의 속성 개수가 적어야 유리함. (O)
2) 테이블 분할
- 테이블 수직 분할: 엔터티의 일부 속성을 별도의 엔터티로 분할 (1:1 관계 성립)
- 테이블 수평 분할: 엔터티의 인스턴스를 특정 기준으로 별도의 엔터티로 분할 (파티셔닝)
- 테이블 수평 분할을 할 경우 관계가 없는 다수의 테이블이 생성됨.
- 테이블 추가
- 중복 테이블 추가: 데이터의 중복을 감안하더라도 성능상 반드시 필요하다고 판단되는 경우 별도의 엔터티를 추가
- 통계 테이블 추가
- 이력 테이블 추가
- 부분 테이블 추가
예제
테이블 수직 분할에 대한 설명으로 가장 적절하지 않은 것?
1) 테이블의 일부 속성을 별도의 테이블로 분리하는 것
2) 테이블을 수직 분할하면 한 개의 블록에 더 많은 인스턴스를 저장할 수 있게 된다.
3) 테이블을 수직 분할하는 경우 1:1 관계 또는 1:M 관계가 형성될 수 있다.
4) 속성의 사용 빈도나 속성값의 NULL 여부를 기준으로 분할할 수 있다.
정답: 3)번 - 테이블을 수직 분할하면 1:1 관계의 테이블이 두 개 생긴다.
예제
테이블 수평 분할에 대한 설명으로 가장 적절하지 않은 것?
1) 테이블의 특정 인스턴스를 별도의 테이블로 분할하는 것
2) 데이터베이스의 파티셔닝 기법을 주로 이용
3) 테이블을 수평 분할하는 경우 관계가 없는 다수의 테이블이 생성된다.
4) 테이블 수평 분할 기준은 기간이다.
정답: 4)번 - 주로 기간이지만 다른 속성이 될 수도.
예제
테이블을 추가하는 경우 적절하지 않은 것?
1) 애플리케이션에서 용도 구분을 위해 같은 데이터를 다른 테이블에 저장하는 경우
2) 특정 범위의 많은 데이터를 자주 처리하는 경우
3) 정규화로 인한 성능 감소가 발생한 경우
4) 미리 계산된 값을 저장해둠으로써 애플리케이션 성능을 향상시키려는 경우
정답: 1)번 - 단순히 같은 데이터를 여러 테이블에 저장하는 것은 데이터 정합성에 위배될 수도.
2. 컬럼 반정규화
- 중복 컬럼 추가: 업무 프로세스상 JOIN이 필요한 경우가 많아 컬럼을 추가하는 것이 성능 측면에서 유리할 경우 고려
- 파생 컬럼 추가: 프로세스 수행 시 부하가 염려되는 계산값을 미리 컬럼으로 추가하여 보관하는 방식으로 상품의 재고나 프로모션 적용 할인가 등이 이에 해당
- 이력 테이블 컬럼 추가: 대량의 이력 테이블을 조회할 때 속도가 느려질 것을 대비하여 조회 기준이 될 것으로 판단되는 컬럼을 미리 추가해놓는 방식 (최신 데이터 여부 등이 이에 해당)
3. 관계 반정규화 (중복 관계 추가)
- 업무 프로세스상 JOIN이 필요한 경우가 많아 중복 관계를 추가하는 것이 성능 측면에서 유리할 경우 고려
- 데이터의 무결성을 깨뜨릴 위험성 없이 데이터 처리 성능을 향상시킬 수 있는 기법
03) 트랜잭션
- 데이터를 조작하기 위한 하나의 논리적인 작업 단위
예시
온라인에서 퀴즈의 정답을 맞히면 쿠폰을 즉시 발행해주는 이벤트. 쿠폰은 선착순 100명에게만 지급.
다음 작업이 논리적으로 하나의 단위로 묶여야 함.
"이벤트 응모 이력을 저장한다."
"쿠폰을 발행한다."
만약 퀴즈의 정답을 맞춰서 이벤트 응모 이력을 정상적으로 저장했으나 그 순간 선착순 100개의 쿠폰이 모두 소진되었다고 했을 때 쿠폰 발행은 실패하게 되고 이벤트 응모 이력 또한 롤백되어야 바람직한 시스템이라고 볼 수 있다.
04) NULL
1. NULL이란?
- 존재하지 않음, 즉 값이 없음을 의미
2. SQL에서 NULL이 어떻게 처리되는지
- SELECT 수입 - 지출 FROM 테이블
- 가로 연산: NULL이 포함되어 있으면 결과값은 NULL
- SELECT SUM(수입) FROM 테이블
- 세로 연산: 다른 인스턴스의 데이터와 연산할 때는 NULL값 제외
"WHERE COL IS NULL 조건은 COL 값이 NULL인 행을 반환하지만 COL=NULL의 결과는 항상 False"
→ NULL은 '모르는 값'이기 때문에, = NULL 은 성립 여부를 판정할 수 없다.
COUNT(COL1)은 COL1이 NULL이 아닌 행의 개수
데이터 모델링의 순서
ㄱ) 데이터 모델에 맞게 정규화를 수행
ㄴ) 데이터베이스의 용량 및 트랜잭션 유형을 파악
ㄷ) 데이터베이스 성능을 고려하여 반정규화 수행
ㄹ) PK/FK 등을 조정하여 인덱스를 반영함으로써 성능을 향상
ㅁ) 데이터 모델의 성능을 검증
데이터 모델에서 생길 수 있는 이상 현상
- 삽입이상: 기본적으로 주문되지 않은 상품의 정보를 삽입할 수 없으며 강제로 삽입하기 위해서는 존재하지않는 가짜 주문번호를 만들어 주어야 함
- 갱신이상: 중복된 데이터 중 일부만 업데이트되어 데이터의 불일치가 발생하게 되는 현상
- 삭제이상: 데이터 삭제 시 삭제되면 안 되는 데이터까지 덩달아 삭제되는 이상
슈퍼-서브타입 설계
공통 속성을 가진 엔터티를 슈퍼타입으로 만들고,
각기 다른 속성을 가진 하위 엔터티를 서브타입으로 분리해 중복을 줄이고 구조를 명확히 하는 설계 방식.
데이터 모델에 대한 반정규화를 고려할 때 판단요소에 대한 설명으로 가장 적절한 것?
1) 반정규화 정보에 대한 재현의 적시성으로 판단한다. 예를 들어, 빌링의 잔액은 다수 테이블에 대한 다량의 조인이 불가피하므로 데이터 제공의 적시성 확보를 위한 필수 반정규화 대상 정보이다.
2) 탐색 대상 데이터의 크기로 판단한다. 왜냐하면 다량 데이터에 대한 인덱스를 활용한 탐색은 Random 처리의 특성으로 성능 저하가 불가피하다.
→ 이건 단순히 인덱스 구조나 I/O 특성 설명이지, 반정규화 판단 기준으로 쓰이지 않음.
3) RDBMS는 현재 레코드 기준으로 이전 또는 이후 위치의 레코드에 대한 접근이 원천적으로 불가능하므로 반정규화를 하지 않으면 해당 정보에 대한 접근 자체가 불가능하다.
→ RDBMS는 이전/이후 레코드 접근 불가능하다는 건 사실이 아님. ORDER BY, OFFSET/FETCH, 윈도우 함수 등으로 가능.
4) 반정규화 테이블은 집계 테이블에 국한하여 적용하도록 한다.
→ 반정규화는 집계 테이블뿐 아니라 중복 컬럼 추가, 테이블 병합, 코드 테이블 확장 등 다양한 형태로 적용 가능하므로 "집계 테이블에 국한"은 틀림.
'SQLD' 카테고리의 다른 글
| ORACLE과 SQL Server에서의 차이 (2) | 2025.08.19 |
|---|---|
| Part2 - Ch3. 관리 구문 (7) | 2025.08.04 |
| Part2 - Ch2. SQL 활용 (2) | 2025.07.29 |
| Part2 - Ch1. SQL 기본 (4) | 2025.07.28 |
| Part1 - Ch1. 데이터 모델링의 이해 (3) | 2025.07.24 |
