Notice
Recent Posts
Recent Comments
Link
변수의 기록
(데이터베이스) DB 스키마 설계 주의사항 본문
✅ 정규화 (Normalization) 개요
정규화는 데이터의 중복을 최소화하고 이상 현상(Anomaly)을 방지하기 위해 테이블을 구조적으로 나누는 과정입니다. 주로 삽입, 삭제, 갱신 이상 (Insert/Delete/Update Anomalies) 을 방지하는 목적입니다.
✅ 이상 현상 (Anomalies) 예시
1. Insertion Anomaly (삽입 이상)
- 특정 데이터를 저장하려면 불필요한 정보도 같이 저장해야 하는 문제

문제점
1.데이터 중복 dept_id , dept_name 등 중복된 데이터 다수 (실수로 인한 데이터 불일치 가능성도 존재,저장공간 낭비)
2. null 값 많이 쓰이게 됨. ( 임직원 없는 즉 부서만 입력시 혹은 반대 )
올바른 db 설계

직원 , 부서 분리되어 삽입 삭제 등이 용이
-- EMPLOYEE 테이블에 DEPARTMENT 정보까지 있어야 할 때
-- 부서만 등록하고 싶은 경우, 직원을 가짜로 넣어야 함
2. Deletion Anomaly (삭제 이상)
- 하나의 정보를 삭제할 때 연관된 다른 유효한 정보도 함께 삭제되는 문제
문제점
1.직원 정보 삭제시 부서 정보도 같이 사라짐
올바른 db 설계
-- 직원이 모두 퇴사하면, 부서 정보도 같이 삭제될 수 있음
3. Update Anomaly (갱신 이상)
- 중복된 데이터가 여러 군데 존재할 때, 하나만 수정하면 데이터 불일치 발생
문제점
1.특정 컬럼의 명칭이 변경 될 경우 (전체를 업데이트 쳐주는게 아니라면 데이터 불일치성 가능)
올바른 db 설계
✅ Spurious Tuples (가짜 튜플)
- 잘못된 조인으로 인해 존재하지 않아야 할 행이 생성되는 경우
위 두 테이블 natural 조인시
사진과 같이 가짜 튜플 2개가 생성됨. (proj_location으로 조인을 맺어 dept_name이 여러개여서)
올바른 db 설계
부서, 프로젝트 , 부서_프로젝트 연결해주는 3개 테이블로
-- 예: 사진 촬영 회사에서 고객-촬영장소를 분리 후 조인 시
-- 촬영되지 않은 조합이 생겨버릴 수 있음 (Cartesian Product)
-- 잘못된 조인 예시 (가정: 조건 없이 JOIN)
SELECT * FROM CUSTOMER, STUDIO;
✅ NULL이 많은 경우의 문제점
- 조인 결과가 예기치 않게 나올 수 있음
- NULL = NULL 은 FALSE 아님 → UNKNOWN 이므로 필터링이 안됨
- 집계 함수 주의
- AVG, SUM, COUNT(column) 등은 NULL을 제외함
- 불필요한 저장소 낭비
- 특히 오라클에서는 NULL이라도 공간이 약간 사용됨 (CHAR 타입 등)
- NULL 기반 비교가 어렵다
- WHERE column = NULL → 항상 false
- IS NULL, IS NOT NULL로만 체크 가능
✅ 정규화 단계 요약
단계 | 조건 및 목적 | 예시 |
1NF (제1정규형) | 원자값만 저장 (중첩 X) | 전화번호 여러 개 → 별도 테이블로 분리 |
2NF (제2정규형) | 부분 함수 종속 제거 (기본키 일부에 종속) | 학번+과목코드 → 교수명 (X) |
3NF (제3정규형) | 이행 함수 종속 제거 | 직원번호 → 부서코드 → 부서명 (X) |
BCNF | 결정자 이슈 해결 (3NF보다 강화) | 수강번호 → 교수, 교수 → 강의실 (모순 가능) |
4NF, 5NF | 다치종속, 조인 종속 제거 | 주로 특수한 케이스 (대규모 설계에서 검토) |
✅ 정규화 vs 성능
정규화를 지나치게 적용하면 조인 비용 증가로 인해 성능이 떨어질 수 있습니다. 실무에서는 다음과 같은 타협을 합니다.
- 정규화는 기본적으로 적용
- 그러나 조회 성능 향상을 위해 비정규화를 일부 허용
- 예: 자주 사용하는 조합을 미리 테이블로 만들어둠
- 예: 정규화된 테이블과 별도로 리포팅용 통계 테이블 운영
✅ 오라클 기준 간단한 예시
-- 정규화된 테이블 구조 예시
CREATE TABLE DEPARTMENT (
dept_id NUMBER PRIMARY KEY,
dept_name VARCHAR2(100)
);
CREATE TABLE EMPLOYEE (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100),
dept_id NUMBER,
CONSTRAINT fk_dept FOREIGN KEY (dept_id) REFERENCES DEPARTMENT(dept_id)
);
✅ 결론
- 정규화는 데이터 무결성과 유지보수성 확보를 위한 중요한 설계 원칙
- 하지만 성능과의 균형이 중요하므로, 실무에서는 정규화 + 비정규화 병행 설계도 고려
- 반드시 이상 현상 방지 목적에서 시작해 데이터 품질 중심으로 설계할 것
*사진 출처 - 유튜브 쉬운코드
'CS지식 > 데이터베이스 (Database)' 카테고리의 다른 글
(데이터베이스) 트랜잭션 이상현상과 격리 수준 (SQL-92 표준 기반) (0) | 2025.05.23 |
---|---|
(데이터베이스) 설계의 기초: Functional Dependency 정리 (0) | 2025.05.23 |
(데이터베이스) MVCC와 Isolation Level – Oracle 예제 (0) | 2025.05.21 |
(데이터베이스) Lock, Two-Phase Locking(2PL), 데드락 정리(예제 포함) (0) | 2025.05.21 |
(DB)트랜잭션 이상 현상 , Isolation Level 정리 (SQL-92 기준) (0) | 2025.05.20 |