IT Knowledge/Database/images/데이터베이스-정규화-diagram.svg

📌 핵심 개념

데이터 중복을 최소화하고 무결성을 보장하기 위한 테이블 설계 기법

AI 요약 보고서

  • 데이터베이스 설계에서 데이터 중복 최소화와 무결성 확보를 위해 정규화 기법이 중요함.
  • 비정규형 테이블은 고객 정보와 주문, 상품 정보가 중복 저장되어 데이터 일관성 문제 발생 가능.
  • 1차 정규화(1NF)는 반복 그룹 제거 및 원자값 확보를 통해 구조 개선을 도모하며, 예시에서는 상품 정보를 별도 테이블로 분리함.
  • 2차 정규화(2NF)는 부분 종속 제거로 고객, 상품, 주문, 주문 항목 테이블로 분리하여 데이터 중복과 이상 현상 방지.
  • 3차 정규화(3NF)는 이행 종속 제거를 통해 고객 주소와 우편번호를 별도 테이블로 분리, 도시 정보의 변경 시 일관성 유지.
  • 실무에서는 조회 성능 향상 목적으로 역정규화를 수행하기도 하며, 예를 들어 주문 요약 테이블에 고객명과 총액을 저장하여 JOIN 없이 빠른 조회 가능.
  • 참고 자료로는 위키백과의 데이터 정규화 관련 문서가 제시됨.

🎯 실전 사례

정규화 전 (비정규형)

-- ❌ 문제가 많은 테이블
CREATE TABLE orders (
  order_id INT,
  customer_name VARCHAR(100),
  customer_email VARCHAR(100),
  customer_phone VARCHAR(20),
  product_name VARCHAR(100),
  product_price DECIMAL(10,2),
  quantity INT
);
 
-- 데이터 예시
| order_id | customer_name | customer_email | product_name | product_price |
|----------|---------------|----------------|--------------|---------------|
| 1        | 홍길동        | hong@email.com | 노트북       | 1500000       |
| 2        | 홍길동        | hong@email.com | 마우스       | 30000         |
 
-- 문제점:
-- 1. 고객 정보 중복 (홍길동 이메일 변경 시 모든 주문 수정 필요)
-- 2. 상품 가격 변경 시 과거 주문 가격도 변경됨
-- 3. 주문 취소 시 고객/상품 정보도 삭제됨

1차 정규화 (1NF): 원자값

-- ✅ 반복 그룹 제거
-- Before: product_name이 "노트북, 마우스"처럼 여러 값
 
CREATE TABLE orders (
  order_id INT,
  customer_name VARCHAR(100),
  customer_email VARCHAR(100),
  product_id INT,
  product_name VARCHAR(100),
  quantity INT
);

2차 정규화 (2NF): 부분 종속 제거

-- ✅ 테이블 분리
CREATE TABLE customers (
  customer_id INT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(100),
  phone VARCHAR(20)
);
 
CREATE TABLE products (
  product_id INT PRIMARY KEY,
  name VARCHAR(100),
  price DECIMAL(10,2)
);
 
CREATE TABLE orders (
  order_id INT PRIMARY KEY,
  customer_id INT,
  order_date DATE,
  FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
 
CREATE TABLE order_items (
  order_id INT,
  product_id INT,
  quantity INT,
  price DECIMAL(10,2),  -- 주문 당시 가격
  PRIMARY KEY (order_id, product_id),
  FOREIGN KEY (order_id) REFERENCES orders(order_id),
  FOREIGN KEY (product_id) REFERENCES products(product_id)
);

3차 정규화 (3NF): 이행 종속 제거

-- ❌ Before: 도시가 변경되면 우편번호도 변경 필요
CREATE TABLE customers (
  customer_id INT PRIMARY KEY,
  address VARCHAR(200),
  city VARCHAR(100),
  zipcode VARCHAR(10)  -- city에 종속
);
 
-- ✅ After
CREATE TABLE customers (
  customer_id INT PRIMARY KEY,
  address VARCHAR(200),
  zipcode VARCHAR(10)
);
 
CREATE TABLE zipcodes (
  zipcode VARCHAR(10) PRIMARY KEY,
  city VARCHAR(100),
  district VARCHAR(100)
);

💡 실무 팁

언제 역정규화 할까?

-- 조회 성능을 위해 의도적으로 중복 허용
CREATE TABLE order_summary (
  order_id INT PRIMARY KEY,
  customer_name VARCHAR(100),  -- 중복
  total_amount DECIMAL(10,2),  -- 계산 결과 저장
  created_at DATETIME
);
 
-- 이유:
-- - 고객 이름 조회 시 JOIN 불필요
-- - 주문 목록 조회 속도 10배 향상

🔗 참고 자료