Skip to main content

Command Palette

Search for a command to run...

데이터베이스 정규화(Normalization)

Published
5 min read

데이터베이스 정규화(Normalization)은 데이터의 중복을 최소화하고, 이상현상(Anomaly)을 방지하며, 데이터 무결성을 보장하기 위해 테이블 구조를 체계적으로 분해하는 과정입니다.

정규화의 목적

  1. 데이터 중복 제거

    • 같은 데이터가 여러 테이블에 중복 저장되는 것을 방지
  2. 데이터 이상 현상 방지

    • 삽입 이상 : 특정 데이터를 추가할 때 불필요한 다른 정보까지 강제로 넣어야하는 문제

    • 갱신 이상 : 데이터를 수정할 때 중복된 곳을 모두 수정해야 하는 문제

    • 삭제 이상 : 데이터를 삭제할 때 의도치 않은 다른 정보까지 사라지는 문제

  3. 데이터 무결성 유지

    • 관계형 DB의 기본 원칙을 따르고 참조 무결성을 보장

정규화 단계 (Normal Forms)

정규화는 보통 1NF → 2NF → 3NF → BCNF → 고급 정규형 순으로 적용됩니다.


0. 비정규형 (Unnormalized Form)

주문ID고객이름고객전화상품ID상품명수량
1홍길동010-1111A01키보드1
2홍길동010-1111A02마우스2
3김철수010-2222A01키보드1
  • 고객 정보와 상품 정보가 중복 저장되고 있음

  • 삽입/갱신/삭제 이상(Anomaly) 발생 가능


1. 1NF (제1 정규화: 컬럼은 원자값)

테이블의 컬럼은 더 이상 쪼갤 수 없는 원자값(Atomic Value) 을 가져야 한다.

한 칸에 여러 값이 들어가면 안 된다.

주문ID고객이름고객전화상품ID상품명수량
1홍길동010-1111A01키보드1
2홍길동010-1111A02마우스2
3김철수010-2222A01키보드1
  • 현재 테이블은 이미 원자값 형태라 큰 변화는 없음

  • 이 단계에서 주문ID + 상품ID를 복합키로 인식하여 주문상품 관계를 명확히 함


2. 2NF (제2 정규화: 부분 함수 종속 제거)

기본키의 일부 컬럼에만 종속된 속성을 분리해 완전 함수 종속을 만족시킨다.

  • 상품명상품ID에만 종속 → 별도 상품 테이블로 분리

[주문 테이블]

주문ID고객이름고객전화
1홍길동010-1111
2홍길동010-1111
3김철수010-2222

[주문상품 테이블]

주문ID상품ID수량
1A011
2A022
3A011

[상품 테이블]

상품ID상품명
A01키보드
A02마우스

3. 3NF (제3 정규화: 이행 함수 종속 제거)

기본키가 아닌 컬럼이 또 다른 컬럼을 결정하는 이행적 종속을 제거한다.

  • 고객이름 → 고객전화 종속 발생 → 고객 정보를 별도 테이블로 분리

[고객 테이블]

고객ID고객이름고객전화
C01홍길동010-1111
C02김철수010-2222

[주문 테이블]

주문ID고객ID
1C01
2C01
3C02

[주문상품 테이블]

주문ID상품ID수량
1A011
2A022
3A011

[상품 테이블]

상품ID상품명
A01키보드
A02마우스

4. BCNF (Boyce–Codd Normal Form)

제3 정규형을 만족한 상태에서, 모든 결정자가 후보키가 되도록 테이블을 분리한다.

  • 결정자(Determinant): 컬럼 A의 값이 컬럼 B의 값을 유일하게 결정하면 A → B 관계에서 A를 결정자라고 부른다.

  • 후보키(Candidate Key) : 테이블의 행을 유일하게 식별할 수 있는 최소 컬럼 집합

  • BCNF 조건: 테이블 안에서 결정자 역할을 하는 모든 컬럼(또는 컬럼 조합)은 반드시 후보키여야 한다.

  • 복잡한 다대다 관계나 복합키에서 특히 자주 나타나는 이상 현상을 더 엄격히 제거하는 단계.


📌 예시

강의 테이블

강의ID교수ID강의실
L01P01R101
L02P01R101
L03P02R202
  • 기본키: (강의ID, 교수ID)

  • 교수ID → 강의실 관계가 존재

  • 하나의 강의ID가 여러 교수에게 배정될 수 있다는 상황

  • 문제: 교수ID는 후보키가 아닌데 (행을 유일하게 식별할 수 없음) 다른 컬럼(강의실)을 결정하고 있음 → BCNF 위반


BCNF로 분리

[강의 테이블]

강의ID교수ID
L01P01
L02P01
L03P02

[교수 테이블]

교수ID강의실
P01R101
P02R202
  • 교수ID → 강의실 관계를 별도 테이블로 분리

  • 모든 결정자가 후보키인 상태 → BCNF 만족


정리

  • 1NF: 컬럼은 원자값만 가져야 함

  • 2NF: 복합키 일부에만 종속된 속성 분리 (부분 함수 종속 제거)

  • 3NF: 기본키가 아닌 컬럼 간의 종속 제거 (이행 함수 종속 제거)

  • BCNF: 모든 결정자는 후보키가 되도록 강화


역정규화란 ? (Denormalization)

정규화를 통해 분리한 테이블을 다시 합치거나, 의도적으로 중복 데이터를 허용해 조회 성능을 높이는 설계 방식입니다.

  • 정규화는 데이터 무결성에는 유리하지만, 테이블 수가 많아져 조인 비용이 증가하고 조회 속도가 느려질 수 있습니다.

  • 읽기 위주의 시스템에서는 조인을 줄이고 빠른 조회를 위해 역정규화를 적용하기도 합니다.

중요한 점:

역정규화는 정규화의 반대 개념이 아니라, 성능과 무결성 사이에서 균형을 맞추기 위한 선택입니다.

More from this blog

낙관적 락(Optimistic Lock)과 비관적 락(Pessimistic Lock)

락(Lock)의 필요성 현대 애플리케이션은 대부분 동시성(Concurrency) 문제에 직면합니다. 여러 사용자나 프로세스가 동시에 같은 데이터를 수정하거나, 은행 계좌 이체와 같은 중요한 트랙잭션을 동시에 실행하는 경우가 있습니다. 이때 동시 접근을 적절히 제어하지 않으면, 데이터 불일치, 중복 처리, 시스템 오류까지 발생할 수 있습니다. 이를 방지하기 위해 락(Lock) 개념이 도입되었습니다. 락은 여러 프로세스나 스레드가 동시에 동일한 자...

Aug 22, 20253 min read

Java 프로그램이 실행되는 흐름

자바 프로그램은 단순히 .java 파일을 실행하는 것이 아니라, 컴파일 → 로드 → 실행 이라는 여러 단계를 거쳐 최종적으로 CPU 가 이해할 수 있는 기계어로 변환됩니다. 이 과정에서 JDK, JVM, JRE가 각각 어떤 역할을 하는지 이해하는 것이 중요합니다. 1. 소스 코드 작성과 컴파일 개발자는 자바 소스 파일(.java)을 작성 JDK 에 포함된 javac (Java Compiler)가 소스 코드를 컴파일 하여 JVM이 이해할 수...

Aug 21, 20252 min read

Java Collection Framework

컬렉션 프레임워크(Collection Framework)란? 자바에서 컬렉션 프레임워크란 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스와 인터페이스 집합입니다. 즉, 데이터를 저장하는 자료구조과 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현한 것입니다. 모든 컬렉션 프레임워크는 자바의 인터페이스를 기반으로 구현됩니다. JFC(Java Collection Framework)의 도입 배경 JCF 이전에는 ...

Aug 14, 20254 min read

운영체제의 발전: 단일 프로세스에서 멀티코어까지

운영체제의 발전은 ‘CPU를 얼마나 효율적으로 활용하느냐’의 역사라고 볼 수 있습니다. 초기에는 한 번에 하나의 프로그램만 실행했지만, 점차 CPU 사용률과 사용자 경험을 높이기 위해 멀티프로그래밍, 멀티태스킹, 멀티프로세스, 멀티스레딩, 그리고 멀티코어 구조가 발전했습니다. 들어가기에 앞서 프로세스와 스레드에 대해 간단히 설명하겠습니다. 프로세스(Process) 실행 중인 프로그램으로 OS로부터 독립된 주소 공간과 자원을 할당 받음 각 ...

Aug 13, 20252 min read

Keep-Alive (HTTP Keep-Alive와 TCP Keep-Alive)

Keep-Alive는 연결(Connection)을 계속 유지하기 위한 메커니즘입니다. 네트워크에서 어떤 연결을 만들고, 요청/응답을 주고받은 후 바로 끊지 않고 일정 시간 동안 유지하면, 그 시간 안에 들어오는 추가 요청은 이미 열린 연결을 재사용할 수 있습니다. 이를 통해 매번 연결을 새로 맺는데 필요한 오버헤드(3-Way Handshake)를 줄일 수 있고, 불필요한 지연(latency)를 감소시킬 수 있습니다. 하지만 연결을 너무 오래 유...

Aug 12, 20252 min read

gaeng

22 posts