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배 향상