변수의 기록

(데이터베이스) DB 스키마 설계 주의사항 본문

CS지식/데이터베이스 (Database)

(데이터베이스) DB 스키마 설계 주의사항

불광동 물주먹 2025. 5. 23. 01:08

✅ 정규화 (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이 많은 경우의 문제점

  1. 조인 결과가 예기치 않게 나올 수 있음
    • NULL = NULL 은 FALSE 아님 → UNKNOWN 이므로 필터링이 안됨
  2. 집계 함수 주의
    • AVG, SUM, COUNT(column) 등은 NULL을 제외함
  3. 불필요한 저장소 낭비
    • 특히 오라클에서는 NULL이라도 공간이 약간 사용됨 (CHAR 타입 등)
  4. 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)
);

✅ 결론

  • 정규화는 데이터 무결성과 유지보수성 확보를 위한 중요한 설계 원칙
  • 하지만 성능과의 균형이 중요하므로, 실무에서는 정규화 + 비정규화 병행 설계도 고려
  • 반드시 이상 현상 방지 목적에서 시작해 데이터 품질 중심으로 설계할 것

 

 

 

*사진 출처 - 유튜브 쉬운코드