2025년 10월 30일

모델링 정규화 1NF~5NF: 개념, 판별 체크리스트, 단계별 분해와 SQL 예제

정규화(Normalization)는 “테이블을 많이 쪼개는 기술”이 아니라, 함수적 종속(Functional Dependency)과 비즈니스 규칙을 키/외래키/제약조건으로 고정해서
데이터 중복과 이상(Anomaly)을 줄이는 데이터 품질·유지보수성 중심의 설계 원칙입니다.

A visual representation of database normalization from 1NF to 5NF, showing a staircase design that illustrates the progression between normalization forms with corresponding tables.

1) 정규화가 필요한 이유: 3가지 이상(Anomaly)을 구조적으로 제거한다

정규화가 직접적으로 줄여주는 대표 문제는 아래 3가지입니다.

  • 삽입 이상(Insertion Anomaly)
    일부 정보가 없으면 행을 추가할 수 없거나, “필수값을 채우기 위해 더미 데이터를 넣는” 상황이 발생
  • 갱신 이상(Update Anomaly)
    같은 정보가 여러 행에 중복되어 한 곳만 수정하면 불일치 발생
  • 삭제 이상(Deletion Anomaly)
    한 행 삭제가 의도치 않게 “다른 의미의 정보”까지 함께 사라짐

정규화의 핵심은 단순합니다.

  • 의미를 고정하는 키(Primary Key / Candidate Key)
  • 관계를 고정하는 외래키(Foreign Key)
  • 규칙을 고정하는 유니크/체크/NOT NULL 제약
  • 그리고 그 바탕이 되는 함수적 종속(FD)과 다중값 종속(MVD)
인서션 이상(Insertion Anomaly), 업데이트 이상(Update Anomaly), 삭제 이상(Deletion Anomaly)에 대한 설명을 포함한 인포그래픽.

2) 핵심 용어 1분 정리(정규형 판별의 언어)

정규화를 “외워서 적용”하려면 금방 한계가 오고, “종속성 언어”로 이해하면 설계가 빨라집니다.

  • 원자값(Atomic): 한 컬럼(셀)에 값 하나만. (CSV/배열/튜플 금지)
  • 후보키(Candidate Key): 행을 유일하게 식별하는 최소 속성 집합
  • 슈퍼키(Superkey): 행을 유일하게 식별할 수 있는 속성 집합(최소가 아닐 수 있음)
  • 프라임 속성(Prime Attribute): 어떤 후보키에라도 포함되는 속성
  • 비키 속성(Non-prime Attribute): 어떤 후보키에도 포함되지 않는 속성
  • 함수적 종속(FD, X → Y): X가 같으면 Y도 항상 같다. (결정자: X)
  • 다중값 종속(MVD, X ↠ Y): X가 고정되면 Y가 “독립적인 다중 목록”으로 반복
  • 조인 종속(JD): 릴레이션이 여러 하위 릴레이션들의 조인으로만 정확히 표현됨(비자명 JD)

실무 팁: FD는 “데이터에서 통계로 추정”하기 전에, 먼저 업무 규칙과 유니크 제약에서 출발하는 것이 안전합니다.
(예: “교사 1명은 과목 1개만 맡는다”, “상품ID는 상품명을 결정한다” 등)


3) 1NF~3NF: “주문” 예제로 단계별 분해(UNF → 1NF → 2NF → 3NF)

아래 예제는 교육용으로 “정규화 단계별 문제를 명확히 드러내는” 형태로 구성했습니다.
(SQL Server 기준이며, TEXT는 사용하지 않고 NVARCHAR(MAX) 또는 길이 제한 문자열을 사용합니다.)

3.0 정규화 전(UNF) — 반복 그룹/다중값 포함

개념적으로 아래처럼 “주문 1건 안에 품목 리스트가 들어가는 구조”는 RDB 관점에서 UNF에 가깝습니다.

Orders_UNF(
  OrderID, OrderDate,
  CustomerID, CustomerName, CustomerPhone, ShipAddress,
  Items = [
    { ProductID, ProductName, SupplierID, SupplierName, Qty, UnitPrice },
    ...
  ]
)

문제:

  • Items가 반복 그룹(다중값) → 원자값 위반
  • 고객/공급사/상품명이 주문·품목에 반복 → 갱신 이상 위험
UNF to 1NF transformation diagram illustrating the removal of repeating groups and the resolution of insertion, update, and deletion anomalies in order data.

3.1 1NF — 원자값/반복그룹 제거(헤더/라인 분리)

1NF 규칙(실무 체크):

  • 모든 컬럼은 원자값
  • 반복 그룹은 “자식 테이블”로 분리
  • PK로 중복 행 방지

1NF DDL (SQL Server)

-- 1) 주문 헤더 (1NF: 고객 정보가 주문에 중복되는 상태를 일부러 남겨 3NF에서 제거할 예정)
CREATE TABLE dbo.Orders_1NF
(
    OrderID        BIGINT       NOT NULL CONSTRAINT PK_Orders_1NF PRIMARY KEY,
    OrderDate      DATE         NOT NULL,
    CustomerID     BIGINT       NOT NULL,
    CustomerName   NVARCHAR(100) NOT NULL,
    CustomerPhone  NVARCHAR(30)  NULL,
    ShipAddress    NVARCHAR(200) NOT NULL
);
GO

-- 2) 주문 품목(반복그룹 분리)
-- 교육용으로 2NF 설명을 위해 합성키(PK: OrderID, ProductID)를 사용
CREATE TABLE dbo.OrderItem_1NF
(
    OrderID        BIGINT        NOT NULL,
    ProductID      BIGINT        NOT NULL,

    ProductName    NVARCHAR(200) NOT NULL,
    SupplierID     BIGINT        NOT NULL,
    SupplierName   NVARCHAR(200) NOT NULL,

    Qty            INT           NOT NULL,
    UnitPrice      DECIMAL(10,2) NOT NULL,

    CONSTRAINT PK_OrderItem_1NF PRIMARY KEY (OrderID, ProductID),
    CONSTRAINT FK_OrderItem_1NF_Orders FOREIGN KEY (OrderID) REFERENCES dbo.Orders_1NF(OrderID)
);
GO

실무 참고: 현실에서는 한 주문에 동일 상품이 여러 줄로 나올 수 있어 LineNo(품목행번호) 또는 대리키를 PK로 두는 경우가 많습니다.
다만 2NF(부분 종속) 설명을 명확히 하기 위해 여기서는 합성키를 잠시 사용합니다.


3.2 2NF — 부분 함수적 종속(Partial Dependency) 제거

2NF는 “합성 후보키가 존재할 때” 의미가 커집니다.
(단일 키만 쓰는 구조에서는 2NF 문제가 구조적으로 발생하지 않는 경우가 많습니다.)

현재 dbo.OrderItem_1NF의 키는 (OrderID, ProductID) 입니다.
그런데:

  • ProductID → ProductName
  • ProductID → SupplierID
  • ProductID → SupplierName (현실적으로는 SupplierID → SupplierName이 더 정확하지만, 결과적으로 ProductID로 결정되는 값이 되어 중복이 커짐)

즉, ProductName/Supplier...는 “키 전체”가 아니라 “키의 일부(ProductID)”에만 의존 → 2NF 위반.

2NF 분해

-- 상품 마스터(2NF 단계: 상품 자체의 속성을 분리)
CREATE TABLE dbo.Product_2NF
(
    ProductID      BIGINT        NOT NULL CONSTRAINT PK_Product_2NF PRIMARY KEY,
    ProductName    NVARCHAR(200) NOT NULL,
    SupplierID     BIGINT        NOT NULL,
    SupplierName   NVARCHAR(200) NOT NULL,
    DefaultPrice   DECIMAL(10,2) NULL
);
GO

-- 주문 품목에서 상품 속성 제거(키 전체 의존만 남김)
CREATE TABLE dbo.OrderItem_2NF
(
    OrderID    BIGINT        NOT NULL,
    ProductID  BIGINT        NOT NULL,
    Qty        INT           NOT NULL,
    UnitPrice  DECIMAL(10,2) NOT NULL, -- 거래 당시 가격(이력 보존)

    CONSTRAINT PK_OrderItem_2NF PRIMARY KEY (OrderID, ProductID),
    CONSTRAINT FK_OrderItem_2NF_Orders FOREIGN KEY (OrderID) REFERENCES dbo.Orders_1NF(OrderID),
    CONSTRAINT FK_OrderItem_2NF_Product FOREIGN KEY (ProductID) REFERENCES dbo.Product_2NF(ProductID)
);
GO

실무 포인트(가격 컬럼 배치):

  • Product.DefaultPrice = “표준/현재 가격”
  • OrderItem.UnitPrice = “거래 당시 가격(히스토리)”
    이 분리가 되어야 “가격 변경”이 발생해도 과거 주문 금액이 흔들리지 않습니다.
테이블에서 합성키의 부분 종속성을 설명하는 이미지로, 위에는 주문 세부 사항이 보이고, 아래에는 분해된 두 개의 테이블이 나열되어 있습니다.

3.3 3NF — 전이적 종속(Transitive Dependency) 제거(비키 → 비키 금지)

3NF를 쉬운 말로 바꾸면:

  • 비키 속성이 다른 비키 속성에 의존하지 않게 하라
  • 마스터 데이터(고객/공급사 같은 “명사”)는 별도 엔터티로 분리하라

현재 남아있는 전형적인 전이적 종속은:

  • CustomerID → CustomerName, CustomerPhone
    (Orders에 고객명이 중복 저장되어 있으면, 고객명 변경 시 갱신 이상)
  • SupplierID → SupplierName
    (상품마다 공급사명이 중복 저장되어 있으면, 공급사명 변경 시 갱신 이상)

3NF 분해(고객/공급사 마스터 분리)

-- 고객 마스터
CREATE TABLE dbo.Customer
(
    CustomerID    BIGINT        NOT NULL CONSTRAINT PK_Customer PRIMARY KEY,
    CustomerName  NVARCHAR(100) NOT NULL,
    CustomerPhone NVARCHAR(30)  NULL
);
GO

-- 공급사 마스터
CREATE TABLE dbo.Supplier
(
    SupplierID    BIGINT        NOT NULL CONSTRAINT PK_Supplier PRIMARY KEY,
    SupplierName  NVARCHAR(200) NOT NULL
);
GO

-- Product_2NF에서 공급사명 제거 → Supplier로 정규화
CREATE TABLE dbo.Product
(
    ProductID      BIGINT        NOT NULL CONSTRAINT PK_Product PRIMARY KEY,
    ProductName    NVARCHAR(200) NOT NULL,
    SupplierID     BIGINT        NOT NULL,
    DefaultPrice   DECIMAL(10,2) NULL,
    CONSTRAINT FK_Product_Supplier FOREIGN KEY (SupplierID) REFERENCES dbo.Supplier(SupplierID)
);
GO

-- Orders_1NF에서 고객명/전화 제거 → Customer로 정규화
CREATE TABLE dbo.Orders
(
    OrderID      BIGINT        NOT NULL CONSTRAINT PK_Orders PRIMARY KEY,
    OrderDate    DATE          NOT NULL,
    CustomerID   BIGINT        NOT NULL,
    ShipAddress  NVARCHAR(200) NOT NULL,
    CONSTRAINT FK_Orders_Customer FOREIGN KEY (CustomerID) REFERENCES dbo.Customer(CustomerID)
);
GO

결과:
고객명/공급사명 변경이 “한 곳에서만” 발생 → 갱신 이상 제거
그리고 FK로 참조 무결성까지 고정 → 데이터 일관성 상승

Transitive Dependency diagram illustrating customer information, order details, product information, and supplier details, showcasing the decomposition of tables for normalization.

4) BCNF: 3NF로도 남는 “결정자(Determinant)” 문제

BCNF(Boyce–Codd Normal Form)는 3NF보다 한 단계 엄격합니다.

  • BCNF 정의(직관): 모든 결정자(X→Y에서 X)는 슈퍼키여야 한다.
  • 3NF는 예외가 있음: 결정자가 슈퍼키가 아니어도, RHS가 프라임 속성이면 허용

4.1 3NF이지만 BCNF 위반인 대표 예

함수적 종속:

  • (Student, Course) → Teacher
  • Teacher → Course
CREATE TABLE dbo.SC_Teacher
(
    Student NVARCHAR(100) NOT NULL,
    Course  NVARCHAR(100) NOT NULL,
    Teacher NVARCHAR(100) NOT NULL,
    CONSTRAINT PK_SC_Teacher PRIMARY KEY (Student, Course)
);
GO

여기서 Teacher → Course의 결정자 Teacher는 슈퍼키가 아닙니다. → BCNF 위반

4.2 BCNF로 분해

-- 교사가 담당 과목을 결정
CREATE TABLE dbo.TeacherCourse
(
    Teacher NVARCHAR(100) NOT NULL CONSTRAINT PK_TeacherCourse PRIMARY KEY,
    Course  NVARCHAR(100) NOT NULL
);
GO

-- 학생이 어떤 교사에게 배우는지
CREATE TABLE dbo.StudentTeacher
(
    Student NVARCHAR(100) NOT NULL,
    Teacher NVARCHAR(100) NOT NULL,
    CONSTRAINT PK_StudentTeacher PRIMARY KEY (Student, Teacher),
    CONSTRAINT FK_StudentTeacher_TeacherCourse FOREIGN KEY (Teacher) REFERENCES dbo.TeacherCourse(Teacher)
);
GO

실무 관점 포인트: BCNF 분해는 의존성 보존(Dependency Preservation)을 항상 보장하지 않을 수 있습니다.
“한 번의 테이블 체크로 규칙을 검증할 수 있는지”까지 함께 검토해야 합니다.

A diagram illustrating the differences between 3NF and BCNF in database normalization, showing a relationship between students, courses, and teachers along with a decomposition into separate entities.

5) 4NF: 다중값 종속(MVD) 제거(독립 다중 목록 분리)

4NF 정의(직관):
한 엔터티에 대해 서로 독립적인 다중 목록(다중값 사실)이 공존하면 분리해야 합니다.

예: 사람(Person)은 여러 Skill과 여러 Language를 가질 수 있지만, 스킬과 언어는 서로 독립입니다.

5.1 4NF 위반 테이블(중복/카티션 폭발)

CREATE TABLE dbo.PersonSkillLang
(
    Person   NVARCHAR(100) NOT NULL,
    Skill    NVARCHAR(100) NOT NULL,
    Language NVARCHAR(100) NOT NULL,
    CONSTRAINT PK_PersonSkillLang PRIMARY KEY (Person, Skill, Language)
);
GO
  • Person ↠ Skill
  • Person ↠ Language
    이 두 MVD가 독립이면, (Skill × Language) 만큼 조합이 늘어나 중복과 이상이 폭발합니다.

5.2 4NF 분해

CREATE TABLE dbo.PersonSkill
(
    Person NVARCHAR(100) NOT NULL,
    Skill  NVARCHAR(100) NOT NULL,
    CONSTRAINT PK_PersonSkill PRIMARY KEY (Person, Skill)
);
GO

CREATE TABLE dbo.PersonLanguage
(
    Person   NVARCHAR(100) NOT NULL,
    Language NVARCHAR(100) NOT NULL,
    CONSTRAINT PK_PersonLanguage PRIMARY KEY (Person, Language)
);
GO

6) 5NF: 조인 종속(JD) 해결(Projection–Join Normal Form)

5NF 정의(직관):
릴레이션이 “여러 부분 릴레이션의 조인 결과로만” 정확히 표현되는 경우(비자명 JD) 분해해야 합니다.

대표적으로 교재에서 나오는 예가 Supplier–Part–Project(SPP) 입니다.

  • SP(Supplier, Part)
  • SJ(Supplier, Project)
  • PJ(Part, Project)

이 3개 관계의 조인을 통해서만 허용되는 SPP가 정확히 복원되는 구조라면 5NF 분해가 가능합니다.

6.1 실무에서 5NF가 드문 이유(중요)

현실에서는 종종 “삼중 제약(Triple Constraint)”이 존재합니다.

예:

  • “프로젝트 P에서는 공급자 S가 부품 A만 납품한다” 같은 제약은
    SP, SJ, PJ의 단순 조인만으로는 표현이 깨질 수 있습니다.

따라서 5NF는:

  • 데이터 의미(제약)까지 유지되는지를 케이스별로 검토해야 하고,
  • 잘못 분해하면 제약을 잃는 설계가 될 수 있습니다.
5NF 구조를 나타내는 이미지로, 공급자, 부품 및 프로젝트를 기반으로 한 관계를 보여주며, SPP(공급자-부품-프로젝트) 조인 구조가 설명되고 있음.

7) 손실 없는 분해(Lossless Join) & 의존성 보존(Dependency Preservation)

정규화는 “쪼개기” 자체보다, 쪼갠 뒤에도 의미가 보존되는지가 핵심입니다.

7.1 손실 없는 분해(2-way 분해의 빠른 판별)

릴레이션 R을 R1, R2로 분해할 때(2-way):

  • R1 ∩ R2R1의 슈퍼키이거나 R2의 슈퍼키이면
    손실 없는 분해(조인 시 가짜 행(spurious tuple) 생성 X)

실무에서는 “교집합 컬럼이 FK로 정확히 연결되는지”가 1차 체크 포인트입니다.

7.2 의존성 보존(로컬 검증 가능성)

이상적인 분해는:

  • 원래 FD/MVD가 분해된 각 테이블에 남아서
    각 테이블의 제약만으로 규칙 검증이 가능한 상태

하지만 BCNF/상위 정규형 분해는 때때로:

  • 손실은 없지만, 의존성 보존이 깨질 수 있습니다.

이 경우 보완 전략:

  • 뷰(View) + 제약/트리거(필요 시)
  • 앱 레벨 검증(권장하지 않음. 최후 수단)
손실 없는 분해 조건을 설명하는 이미지로, 두 개의 릴레이션 R1과 R2의 교집합 속성이 하나의 릴레이션의 슈퍼키여야 함을 나타냄.

8) 정규화 vs 비정규화: 실무에서 어디서 멈출까?

정규형은 “높을수록 무조건 좋다”가 아니라 워크로드와 운영 현실의 문제입니다.

8.1 일반적인 실무 가이드(권장)

  • OLTP(거래계): 보통 3NF ~ BCNF에서 멈추는 경우가 많음
  • 장점: 이상 최소화, 데이터 품질↑, 변경/확장 용이
  • 주의: 조인 비용↑ → 인덱스/캐시/파티셔닝/쿼리 설계로 보완
  • 분석/리포팅/BI: 목적적 비정규화(스타 스키마), 스냅샷 테이블 활용
  • 다만 “원천 정규형 모델(SSOT)” + ETL로 파생 구조를 만드는 패턴이 안정적

8.2 비정규화가 합리적인 경우(조건부)

  • 읽기 위주의 초고속 조회(조인 비용이 병목)
  • 준실시간 대시보드/집계 테이블
  • 단, 원천 정합성(정규형)과 파생(비정규화)을 분리해서 운영하는 것이 안전합니다.

9) 단계별 판별 체크리스트(요약표)

정규형빠른 판별 질문(YES/NO)위반 시 전형적 증상조치
1NF셀에 다중값/CSV/배열이 있는가? 반복그룹이 있는가?행/컬럼에 리스트가 들어감자식 테이블 분리
2NF(합성키일 때) 비키 속성이 키 일부에만 의존하는가?ProductID만으로 ProductName 결정마스터 테이블 분리
3NF비키→비키 전이적 종속이 있는가?CustomerName이 Orders에 중복엔터티(명사) 분리
BCNF모든 결정자(→의 LHS)가 슈퍼키인가?3NF인데도 중복/이상 잔존결정자 기준 추가 분해
4NF독립적인 다중 목록이 한 테이블에 공존하는가?카티션 폭발, 중복 급증목록별 릴레이션 분리
5NF비자명 JD가 존재하여 조인으로만 성립하는 정보인가?희귀. 케이스별 검증 필요도메인 제약 보존 확인 후 분해

10) 자주 묻는 질문(FAQ)

Q1. 3NF와 BCNF의 차이는?

A. 3NF는 “결정자가 슈퍼키가 아니어도 RHS가 프라임 속성이면 허용”하는 예외가 있습니다.
BCNF는 예외 없이 모든 결정자 = 슈퍼키여야 합니다.

Q2. 합성키 대신 대리키(서로게이트 키)를 쓰면 2NF 이슈가 사라지나요?

A. 2NF의 “부분 종속”은 합성 후보키일 때 주로 문제가 됩니다. 대리키를 쓰면 2NF 위반은 구조적으로 줄어들 수 있지만, 3NF/BCNF(전이/결정자) 문제는 여전히 남습니다.
즉, 대리키는 “정규화 자체를 대체하지 않습니다.”

Q3. 가격은 어디에 둬야 하나요?

A. 표준가격은 Product, 거래 당시 가격은 OrderItem에 둬야 합니다. 그래야 가격 이력이 보존됩니다.

Q4. 정규화하면 성능이 나빠지지 않나요?

A. 조인 수가 늘 수 있습니다. 다만 대개 정규화는 데이터 품질/유지보수성을 올리고, 성능은 인덱스/쿼리/캐시/파티셔닝으로 보완합니다.
특히 OLTP에서는 “정합성”이 무너지면 운영 비용이 훨씬 커집니다.

Q5. 4NF/5NF까지 항상 가야 하나요?

A. 아닙니다. 대부분 OLTP는 3NF~BCNF에서 충분합니다. 4NF/5NF는 특수 패턴에서만 이점이 있습니다.

Q6. 손실 없는 분해는 어떻게 빠르게 점검하나요?

A. 2-way 분해는 “교집합 컬럼이 한쪽의 슈퍼키인지”를 먼저 보세요. 복잡한 경우 체이스(Chase)나 모델링 도구 검증을 권장합니다.


11) 실무형 DDL 스캐폴드(권장 형태, SQL Server)

아래는 “정규형 기반 원천 모델(OLTP)”을 만들 때 자주 사용하는 기본 스캐폴드입니다.
(대리키 + 라인번호 패턴 포함)

CREATE TABLE dbo.Customer
(
    CustomerID    BIGINT        IDENTITY(1,1) NOT NULL CONSTRAINT PK_Customer PRIMARY KEY,
    CustomerName  NVARCHAR(100) NOT NULL,
    Phone         NVARCHAR(30)  NULL
);
GO

CREATE TABLE dbo.Supplier
(
    SupplierID    BIGINT         IDENTITY(1,1) NOT NULL CONSTRAINT PK_Supplier PRIMARY KEY,
    SupplierName  NVARCHAR(200)  NOT NULL
);
GO

CREATE TABLE dbo.Product
(
    ProductID     BIGINT         IDENTITY(1,1) NOT NULL CONSTRAINT PK_Product PRIMARY KEY,
    ProductName   NVARCHAR(200)  NOT NULL,
    SupplierID    BIGINT         NOT NULL,
    DefaultPrice  DECIMAL(10,2)  NULL,
    CONSTRAINT FK_Product_Supplier FOREIGN KEY (SupplierID) REFERENCES dbo.Supplier(SupplierID)
);
GO

CREATE TABLE dbo.Orders
(
    OrderID      BIGINT         IDENTITY(1,1) NOT NULL CONSTRAINT PK_Orders PRIMARY KEY,
    OrderDate    DATE           NOT NULL,
    CustomerID   BIGINT         NOT NULL,
    ShipAddress  NVARCHAR(200)  NOT NULL,
    CONSTRAINT FK_Orders_Customer FOREIGN KEY (CustomerID) REFERENCES dbo.Customer(CustomerID)
);
GO

CREATE TABLE dbo.OrderItem
(
    OrderItemID BIGINT         IDENTITY(1,1) NOT NULL CONSTRAINT PK_OrderItem PRIMARY KEY,
    OrderID     BIGINT         NOT NULL,
    LineNo      INT            NOT NULL,
    ProductID   BIGINT         NOT NULL,
    Qty         INT            NOT NULL,
    UnitPrice   DECIMAL(10,2)  NOT NULL,
    CONSTRAINT FK_OrderItem_Orders  FOREIGN KEY (OrderID)  REFERENCES dbo.Orders(OrderID),
    CONSTRAINT FK_OrderItem_Product FOREIGN KEY (ProductID) REFERENCES dbo.Product(ProductID),
    CONSTRAINT UQ_OrderItem_Order_Line UNIQUE (OrderID, LineNo)
);
GO

-- 자주 쓰는 보조 인덱스(조회 패턴에 따라 조정)
CREATE INDEX IX_OrderItem_OrderID   ON dbo.OrderItem(OrderID);
CREATE INDEX IX_OrderItem_ProductID ON dbo.OrderItem(ProductID);
GO

12) 워드프레스/블로그용 구성 팁(가독성과 SEO)

추천 글 구조

  • 서론: 정규화가 필요한 이유(이상 3종 + 비용 관점)
  • 본론: 1NF→3NF “주문 예제” (가장 많이 검색되는 구간)
  • 심화: BCNF/4NF/5NF (검색 유입 + 전문성 강화)
  • 결론: “어디서 멈출까” + 체크리스트

내부/외부 링크 앵커 텍스트 제안

  • 내부 링크:
  • “함수적 종속을 실무에서 추출하는 방법”
  • “OLTP 인덱스 설계 체크리스트”
  • “이력관리(SCD Type 2) 모델링 패턴”
  • 외부 링크(선택):
  • “정규형 개요”
  • “함수적 종속(Functional Dependency) 정의”
  • “Chase 알고리즘 개념”

13) 구조화 데이터(JSON‑LD) 템플릿(선택)

날짜/URL은 실제 게시 정보로 교체하세요.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "모델링 정규화 1NF~5NF: 개념, 판별 체크리스트, 단계별 분해와 SQL 예제 (SQL Server 기준)",
  "description": "정규화 1NF~5NF(BCNF 포함)의 정의와 판별 체크리스트, 손실 없는 분해·의존성 보존, 단계별 분해와 SQL Server DDL 예제를 실무 관점에서 정리합니다.",
  "datePublished": "2026-01-09",
  "dateModified": "2026-01-09",
  "keywords": "데이터베이스 정규화, 1NF, 2NF, 3NF, BCNF, 4NF, 5NF, 데이터 모델링, 함수적 종속",
  "author": { "@type": "Person", "name": "전우석" },
  "mainEntityOfPage": { "@type": "WebPage", "@id": "https://example.com/normalization-1nf-5nf" }
}
</script>

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "3NF와 BCNF의 차이는?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "3NF는 결정자가 슈퍼키가 아니어도 우변이 프라임 속성이면 허용하는 예외가 있으나, BCNF는 모든 결정자가 반드시 슈퍼키여야 합니다."
      }
    },
    {
      "@type": "Question",
      "name": "대리키를 쓰면 2NF 문제가 사라지나요?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "대리키를 쓰면 합성키 기반의 부분 종속(2NF 위반)은 줄어들 수 있지만, 전이적 종속(3NF)이나 결정자 문제(BCNF)는 여전히 남을 수 있어 별도 검토가 필요합니다."
      }
    },
    {
      "@type": "Question",
      "name": "가격은 어디에 저장해야 하나요?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "표준가격은 상품 마스터(Product)에, 거래 당시 가격은 주문 품목(OrderItem)의 UnitPrice에 저장해 가격 이력을 보존하는 것이 일반적입니다."
      }
    }
  ]
}
</script>