# 데이터베이스 정규화 (Database Normalization) 데이터베이스 정규화는 관계형 데이터베이스에서 데이터 중복을 최소화하고 무결성을 높이기 위한 설계 기법이다. 정규화는 데이터의 논리적 구조를 나누어 서로 의존하는 속성을 분리하고, 데이터 삽입/삭제/갱신 시 발생할 수 있는 이상현상(update anomaly, insert anomaly, delete anomaly)을 방지하는 것을 목표로 한다. --- ## 개요 - 목적 - 데이터 중복 제거 - 데이터 무결성 및 일관성 유지 - 데이터 수정의 이상현상 감소 - 유지보수 용이성 향상 - 원리 - 함수적 종속, 다치 종속, 조인 종속 등 데이터 간 의존성을 분석하여 테이블을 분해한다. - 각 분해 결과는 후보키(Candidate Key) 기반으로 구성된 정규형의 제약을 만족한다. - 주요 용어 - 정규화(Normalization) - 비정규형(또는 반정규화 Denormalization) = 성능 향상을 위해 의도적으로 정규화를 해제하는 기법 - 기능적 종속(Functionally Dependent) - 다치 종속(Multi-Valued Dependency) - 조인 종속(Join Dependency) --- ## 역사 - 1970년대에 데이터베이스 설계 이론으로 체계화되기 시작했다. - 에드가 F. Codd의 관계형 데이터 모델 제안과 함께 정규화 개념이 정립되었고, 이후 BCNF, 4NF, 5NF 등으로 발전하였다. - 현대 데이터베이스 시스템에서는 정규화가 표준 설계의 기본으로 간주되나, 성능 요구에 따라 일부 반정규화가 병행된다. --- ## 핵심 용어 - 관계(Relation): 테이블 형태의 데이터 구조로, 속성들의 집합(컬럼)과 튜플의 모임이다. - 속성(Attribute): 테이블의 열을 나타내며, 도메인(domain)을 가진다. - 후보키(Candidate Key): 후보가 되는 각 가능한 기본 키의 집합이다. - 기본키(Primary Key): 관계를 고유하게 식별하는 하나의 키이다. - 함수적 종속(Functionally Dependent): X가 존재하면 Y도 결정되는 관계의 제약을 말한다. X → Y가 성립하면 X가 주 키 또는 부분키로 작용하는 경우가 많다. - 부분 함수적 종속(Partial Dependency): 후보키의 부분집합이 비키 속성을 결정하는 경우. - 트랜스티브 종속(Transitive Dependency): 비키 속성이 다른 비키 속성에 의해 결정되는 경우. - 다치 종속(Multi-Valued Dependency, MVD): 한 속성 집합이 다른 속성 집합과 독립적으로 여러 값을 가질 수 있는 경우. - 정규형(Normal Form): 정규화의 단계로, 특정 제약을 만족하는 관계의 형태를 말한다. --- ## 정규화의 형태 (Normal Forms) ### 1NF (First Normal Form) - 정의 - 모든 속성이 원자적(atomic) 값을 가져야 한다. 반복되는 그룹이나 다중 값의 속성이 없어야 한다. - 특징 - 테이블의 각 셀은 한 가지 값만 가진다. - 예: 학생-수강 정보를 한 튜플에 여러 과목이 들어가지 않도록 각 과목을 따로 행으로 분리한다. - 예시 - 비정규형: 학생ID, 학생이름, 과목들(수학, 과학, 영어) - 1NF로 정규화: 학생ID, 학생이름, 과목ID ### 2NF (Second Normal Form) - 정의 - 1NF를 만족하고, 모든 비키 속성이 기본키의 전체 함수적 종속을 가져야 한다. 즉, 부분 함수적 종속이 없어야 한다. - 특징 - 복합키를 갖는 관계에서만 부분 종속 문제를 제거한다. - 예시 - R(studentID, courseID, studentName, courseName) - 기본키가 (studentID, courseID)인 경우, studentName은 studentID에만 종속되므로 2NF 위반. 이를 분리하여: - R1(studentID, studentName) - R2(studentID, courseID, courseName) ### 3NF (Third Normal Form) - 정의 - 2NF를 만족하고, 모든 비키 속성이 다른 비키 속성에 의해 결정되지 않는다(즉, 비키 속성 간의 트랜스티브 종속 제거). - 특징 - 후보키가 아닌 속성 간의 의존성을 제거한다. - 예시 - R3(studentID, courseID, courseName, instructor) - courseName, instructor가 courseID에 의해 결정된다면, 이를 분리: - R2(studentID, courseID) - R3(courseID, courseName, instructor) ### BCNF (Boyce-Codd Normal Form) - 정의 - 3NF를 강화한 형태로, 모든 결정자가 반드시 후보키여야 한다는 조건을 추가로 요구한다. - 특징 - 3NF보다 더 강력한 제약으로, 특정 상황에서 3NF를 만족하더라도 BCNF를 만족하지 못하는 경우가 존재할 수 있다. - 예시 - 특정 릴레이션에서 (A, B) → C 와 (B) → D 와 같은 다중 종속이 있을 때, A가 후보키가 아니면 BCNF 위반이 될 수 있다. - 실무적 노트 - BCNF는 이론적으로 강력하지만, 현실 데이터 모델에서는 과도한 분해로 인해 조인이 많아져 성능 저하가 발생할 수 있어 상황에 따라 3NF의 균형을 취하기도 한다. ### 4NF (Fourth Normal Form) - 정의 - BCNF를 만족하고, 다치 종속(MVD)을 제거한다. - 특징 - 하나의 속성 집합이 서로 독립적으로 여러 값을 취하는 경우를 분리한다. - 예시 - 예를 들어 하나의 학생이 여러 전화번호와 여러 이메일 주소를 가질 수 있고, 이 두 속성이 서로 독립적으로 존재하는 경우를 4NF로 분리한다: - StudentPhones(studentID, phone) - StudentEmails(studentID, email) ### 5NF (Fifth Normal Form, PJNF) - 정의 - 조인 종속(Join Dependency, JD)을 만족시키며, 더 이상 분해해도 정보 손실 없이 조인이 가능하도록 한다. - 특징 - 이론적으로 가장 정교한 형태이나, 실제 시스템에서의 적용은 매우 드물다. - 실무적 고려 - 5NF까지의 정규화는 대부분의 비즈니스 시스템에서 필요 이상일 수 있으며, 조인 종속의 복잡성을 관리하기 어렵고 변동성이 큰 데이터 모델에서는 반정규화의 필요성이 더 커질 수 있다. --- ## 정규화의 장단점 - 장점 - 데이터 중복 감소로 저장 공간 절감 - 데이터 무결성 유지 및 수정/삭제 시 이상현상 감소 - 데이터 독립성과 확장성 향상 - 단점 및 주의점 - 지나친 정규화로 인한 조인 비용 증가 - 쿼리 복잡성 증가와 성능 저하 가능성 - 운영 환경에 따라 반정규화가 필요할 수 있음 - 실무 팁 - 초기 설계 시 3NF 또는 BCNF를 기본으로 시작하고, 성능 문제가 확인되면 반정규화를 고려한다. - 트랜잭션 일관성을 유지하면서 읽기 중심의 워크로드에서는 조인 비용을 고려한 반정규화를 적용할 수 있다. - 데이터 마이그레이션과 스키마 변경 시 무결성 검증을 자동화한다. --- ## 정규화 설계의 실무 팁 - 모델링 순서 - 요구사항 분석 → 엔티티/속성 도출 → 후보키 도출 → 종속성 분석 → 정규화 단계별 분해 - 도구와 기법 - ER 다이어그램, 데이터 딕셔너리, 스키마 버전 관리 - 성능과 일관성의 균형 - 읽기 위주 트랜잭션은 정규화된 구조가 유리하고, 고속 조회가 필요한 경우 반정규화 또는 캐시 계층 도입 고려 - 데이터 품질 관리 - 제약 조건(외래키, 고유 제약, 체크 제약)을 명확히 정의하고 데이터 로딩 시 검증 로직을 강화 --- ## 간단한 예시: 학생-강의 시스템의 정규화 과정 상황: 학생이 여러 강의를 듣고, 강의는 하나의 강의명과 교수를 가진다고 가정한다. 초기 관계 R은 아래와 같다고 보자. - R(StudentID, StudentName, CourseID, CourseName, Instructor) 1) 1NF - 이미 원자값으로 구성되어 있다고 가정. - R1(StudentID, StudentName, CourseID, CourseName, Instructor) 2) 2NF - 기본키가 (StudentID, CourseID)로 가정될 때, 일부 속성은 부분적으로만 의존한다. - 문제 속성: StudentName은 StudentID에만 의존. - 분해: - R2a(StudentID, StudentName) - R2b(StudentID, CourseID, CourseName, Instructor) 3) 3NF - CourseName, Instructor가 CourseID에 의해 트랜스티브로 결정될 수 있다. - 분해: - R3a(StudentID, CourseID) - R3b(CourseID, CourseName, Instructor) 4) BCNF - 위 R3a, R3b는 보통 BCNF를 만족하지만, 특정 의존 관계에 따라 추가 분해가 필요할 수 있다. - 보통은 R3a와 R3b가 BCNF를 만족하는 경우가 많다. 5) 4NF 및 5NF - 다치 종속 및 조인 종속이 존재하는 경우에만 필요하다. - 예시: 학생의 전화번호와 이메일이 독립적으로 여러 개 존재하는 경우를 별도 테이블로 분리하는 식으로 접근한다. 최종 설계 예시 - 학생 정보: Students(StudentID PK, StudentName) - 강의 정보: Courses(CourseID PK, CourseName, Instructor) - 수강 정보: Enrollments(StudentID PK/FK, CourseID PK/FK) 이와 같이 서로 다른 주제를 담당하는 엔티티를 독립적으로 관리하면 데이터 중복과 이상현상을 크게 줄일 수 있다. --- ## 정규화의 실무 적용 시나리오 - 신규 시스템 설계 시점 - 3NF 또는 BCNF를 기본으로 시작하고, 데이터 모델 변화에 대비한 마이그레이션 계획 수립 - 운영 중인 시스템의 성능 개선 - Read-heavy 트랜잭션에서 조인 비용이 큰 경우, 필요한 부분에 대해 반정규화를 검토 - 데이터 품질 관리 - 무결성 제약조건과 트리거, 검증 로직으로 데이터 품질을 지속적으로 유지 --- ## 관련 도구와 참고 자료 - 데이터 모델링 도구: ER 다이어그램 도구, 스키마 버전 관리 시스템 - 주요 참고 개념 - 함수적 종속, 다치 종속, 조인 종속의 심층 이해 - 정규형 간의 관계 및 설계 패턴 --- ## 추가적으로 읽을 만한 주제 - 정규화 vs. 반정규화 전략 - 트랜잭션 관리와 무결성 제약의 설계 원칙 - 관계형 데이터베이스 설계의 모범 사례 --- 다음은 관련 문서를 안내하는 항목이다. --- 관련 문서: [[Database Normalization Concepts]], [[Functional Dependency]], [[Relational Database Design]], [[SQL Normal Forms]]