티스토리 뷰

목차


    "데이터를 엑셀표처럼 한 곳에 전부 때려 넣었더니, 이름을 하나 수정할 때마다 수백 줄을 고쳐야 하는 끔찍한 경험을 해보셨나요?" 데이터베이스 설계에 있어 가장 기본이 되면서도 많은 실무자와 SQLD 수험생들을 좌절하게 만드는 마의 구간, 바로 '정규화(Normalization)'입니다. 정규화란 한마디로 '데이터의 중복을 최소화하고 무결성을 유지하기 위해 테이블을 쪼개고 구조화하는 과정'을 뜻합니다. 만약 정규화가 제대로 이루어지지 않은 데이터베이스 시스템을 운영한다면, 데이터를 삽입, 수정, 삭제할 때마다 논리적인 모순이 발생하는 끔찍한 '이상 현상(Anomaly)'에 직면하게 됩니다. 기초 공사가 부실한 건물은 작은 지진에도 무너지듯, 정규화가 생략된 데이터베이스는 트래픽이 몰리는 순간 엄청난 시스템 부하와 데이터 오염을 초래합니다. 제1정규형(1NF)부터 실무에서 가장 많이 쓰이는 제3정규형(3NF), 그리고 한 단계 더 엄격한 보이스-코드 정규형(BCNF)까지, 복잡한 학술적 용어를 걷어내고 누구나 직관적으로 이해할 수 있는 완벽한 예시와 단계별 분리 공식을 공백 제외 2,500자의 방대한 데이터베이스 바이블로 아주 명쾌하고 심도 있게 파헤쳐 드립니다.

     

     

     

     

     

    1. 정규화를 해야 하는 이유: 3대 '이상 현상(Anomaly)'의 공포

    정규화의 원리를 파악하기 전에, 우리가 왜 테이블을 힘들게 쪼개야 하는지 그 원인부터 알아야 합니다. 하나의 거대한 테이블에 [학생번호, 학생이름, 학과명, 학과전화번호, 수강과목]을 모두 몰아넣었다고 가정해 봅시다. 이때 세 가지 치명적인 오류가 발생합니다.

    1) 삽입 이상 (Insertion Anomaly)

    새로운 학생이 입학하여 데이터를 넣어야 합니다. 그런데 이 학생이 아직 '수강과목'을 신청하지 않았습니다. 테이블의 기본키(PK)가 [학생번호 + 수강과목]의 복합키라면, 수강과목이 NULL이 될 수 없으므로 이 학생의 정보 자체를 테이블에 아예 삽입할 수 없는 상황이 발생합니다. 원치 않는 더미(Dummy) 데이터를 억지로 넣어야만 삽입이 가능해집니다.

    2) 삭제 이상 (Deletion Anomaly)

    어떤 학생이 특정 과목의 수강을 취소하여 해당 레코드를 삭제하려고 합니다. 그런데 그 과목을 듣는 학생이 오직 그 학생 한 명뿐이었다면 어떻게 될까요? 레코드를 날리는 순간, 데이터베이스에서 '해당 과목'에 대한 정보(과목명, 담당 교수 등)까지 통째로 연쇄 삭제되어 영영 사라져 버립니다. 의도치 않은 정보의 손실이 발생하는 것입니다.

    3) 갱신 이상 (Update Anomaly)

    '컴퓨터공학과'의 학과전화번호가 변경되었습니다. 그런데 이 거대한 테이블에는 컴퓨터공학과 학생이 1,000명이나 등록되어 있습니다. 1,000개의 레코드에 있는 전화번호를 전부 업데이트해야 하는데, 실수로 999개만 수정하고 1개를 누락한다면 동일한 학과임에도 전화번호가 서로 다른 '데이터의 불일치(모순)'가 발생하게 됩니다. 정규화는 바로 이러한 세 가지 이상 현상을 원천적으로 제거하는 과정입니다.

     

    [데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드
    [데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드

    2. 제1정규형 (1NF): "모든 값은 쪼갤 수 없는 '원자값'이어야 한다"

    정규화의 가장 기초 단계인 1NF(First Normal Form)의 핵심 키워드는 '원자성(Atomicity)'입니다.

    1) 1NF의 개념과 위반 사례

    릴레이션(테이블)에 속한 모든 속성의 값은 더 이상 쪼갤 수 없는 단일한 값, 즉 원자값만 가져야 합니다. 만약 '홍길동'이라는 학생의 [수강과목] 컬럼에 "데이터베이스, 자료구조, 운영체제"처럼 콤마(,)로 구분된 여러 개의 값이 한 칸에 들어가 있다면 이는 제1정규형을 정면으로 위반한 것입니다.

    2) 1NF로의 변환 방법

    콤마로 연결된 데이터를 뜯어내어 레코드를 여러 줄로 분리해야 합니다. 홍길동 레코드 1줄을, 홍길동-데이터베이스, 홍길동-자료구조, 홍길동-운영체제라는 3개의 독립적인 행(Row)으로 나누어 저장합니다. 이렇게 하면 특정 수강과목을 기준으로 데이터를 검색하거나 조인(JOIN)할 때 성능이 보장되며 시스템이 각 속성을 온전한 데이터 모델로 인식할 수 있습니다.

    핵심 요약: 하나의 컬럼(열)에는 반드시 하나의 값만 존재해야 한다. 리스트나 배열 형태의 데이터가 들어가는 순간 관계형 데이터베이스(RDBMS)의 자격을 상실합니다.

     

     

     

     

    3. 제2정규형 (2NF): "부분 함수 종속을 제거하라"

    제1정규형을 만족했다면, 이제 기본키(PK)와 일반 속성 간의 관계를 따져볼 차례입니다. 2NF의 핵심은 '부분 함수 종속(Partial Functional Dependency)'의 완전한 제거입니다.

    1) 2NF의 개념과 함수 종속성

    테이블의 기본키가 두 개 이상의 컬럼으로 결합된 '복합키(Composite Key)'일 때만 발생하는 문제입니다. 예를 들어 테이블의 PK가 [학생번호 + 과목코드]라고 해보겠습니다. 이 테이블에는 [성적]과 [학생이름]이라는 일반 속성이 있습니다. [성적]은 학생이 어떤 과목을 들었는지 두 개의 키를 모두 알아야만 결정되므로 '완전 함수 종속'입니다. 하지만 [학생이름]은 오직 '학생번호' 하나만 알아도 결정됩니다. 복합키의 일부분에만 종속되어 있는 현상, 이것이 바로 '부분 함수 종속'입니다.

    2) 테이블 쪼개기의 시작

    학생번호에만 종속되는 [학생이름] 정보를 이 테이블에 그대로 두면, 해당 학생이 과목을 수강할 때마다 학생 이름이 불필요하게 중복 저장됩니다. 따라서 [학생번호, 학생이름]만을 가진 별도의 '학생 테이블'을 완전히 분리해 내야 합니다. 분리 후 기존 테이블에는 [학생번호(FK), 과목코드(FK), 성적]만 남겨 완전 함수 종속을 만족시킵니다.

    시험 대비 팁: 만약 어떤 테이블의 기본키(PK)가 단일 컬럼으로 구성되어 있다면, 복합키가 아니기 때문에 부분 함수 종속 자체가 성립할 수 없습니다. 즉, 단일 키 테이블은 제1정규형만 만족하면 자동으로 제2정규형까지 만족하게 됩니다.

     

    [데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드
    [데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드

    4. 제3정규형 (3NF): "이행적 함수 종속을 끊어내라"

    실무 데이터 모델링에서 가장 보편적으로 맞추는 표준 정규형이 바로 제3정규형입니다. 3NF의 핵심 목표는 '이행적 함수 종속(Transitive Functional Dependency)'을 찾아내어 분리하는 것입니다.

    1) 이행적 함수 종속이란? (A → B → C)

    기본키가 아닌 일반 속성들끼리 꼬리를 물고 종속되는 현상을 말합니다. 예를 들어 [학생번호(PK), 학과코드, 학과전화번호]로 구성된 테이블이 있습니다. 학생번호를 알면 소속된 학과코드를 알 수 있습니다 (A → B). 그리고 학과코드를 알면 그 학과의 학과전화번호를 알 수 있습니다 (B → C). 결과적으로 학생번호가 학과전화번호를 결정하는 모양새가 됩니다 (A → C). 이를 이행적 종속이라고 부릅니다.

    2) 3NF 변환: 일반 속성 간의 연결고리 절단

    학과전화번호는 기본키인 학생번호에 직접 종속된 것이 아니라, 일반 속성인 학과코드에 기대어 기생하고 있습니다. 앞서 서론에서 언급한 '갱신 이상'의 주범이 바로 이 현상입니다. 이 꼬리를 끊어내기 위해, 기본키가 아닌 속성에 종속된 부분 [학과코드, 학과전화번호]를 독립적인 '학과 테이블'로 분리해 냅니다. 분리된 학과 테이블의 기본키는 '학과코드'가 되며, 원래 테이블에는 외래키(FK)로서 학과코드만 남겨 연결성을 유지합니다.

    데이터베이스 제약 조건: 실무적으로 3NF를 달성했다는 것은, "테이블 내의 모든 일반 컬럼들이 오직 기본키(PK)에만 직접적으로 의존하고 있다"는 의미입니다. 이렇게 설계되어야 데이터의 논리적 무결성이 견고하게 유지됩니다.

     

     

     

     

    5. BCNF (Boyce-Codd Normal Form): "모든 결정자는 후보키여야 한다"

    제3정규형을 완벽하게 만족했음에도 불구하고, 아주 특수한 상황에서 이상 현상이 발생할 수 있습니다. 이를 막기 위해 3NF를 더욱 강하게 조인 것이 BCNF(보이스-코드 정규형), 일명 '강한 제3정규형'입니다.

    1) BCNF를 위반하는 특수 상황

    테이블의 구성이 [학생번호, 수강과목, 담당교수]라고 가정해 봅시다. 한 과목에 여러 교수가 있을 수 있지만, 한 교수는 오직 한 과목만 가르칩니다. 여기서 복합키(PK)는 [학생번호 + 수강과목]입니다. PK를 알면 '담당교수'를 알 수 있으므로 2NF, 3NF를 모두 통과합니다.
    그런데 역으로 생각해 보면, 일반 속성인 '담당교수'를 알면 '수강과목'이 무엇인지 알 수 있습니다. (담당교수 → 수강과목) 즉, 일반 속성이 뻔뻔하게도 기본키의 일부분을 결정하고 있는 기형적인 하극상 구조가 발생합니다. 여기서 '담당교수'처럼 무언가를 결정하는 속성을 '결정자'라고 부릅니다.

    2) BCNF의 해법과 테이블 분리

    BCNF의 엄격한 규칙은 "결정자 역할을 하는 모든 속성은 반드시 후보키(기본키가 될 수 있는 자격)여야 한다"는 것입니다. 일반 속성인 '담당교수'가 결정자 행세를 하고 있으므로 이를 분리해야 합니다.
    따라서 [학생번호, 담당교수]를 하나의 테이블로, [담당교수, 수강과목]을 또 다른 테이블로 완전히 찢어내야 합니다. 이렇게 하면 교수가 새롭게 부임하여 담당 과목이 정해졌을 때 학생이 등록하지 않아도 정보(과목-교수 매칭)를 원활하게 삽입할 수 있어 삽입 이상을 완벽하게 해결할 수 있습니다.

    정규화의 역설과 반정규화(Denormalization): 1NF에서 BCNF까지 테이블을 무자비하게 쪼개다 보면 데이터 중복은 완벽히 사라집니다. 하지만 데이터를 조회(SELECT)할 때마다 수많은 테이블을 조인(JOIN)해야 하므로 시스템의 성능이 급격히 저하될 수 있습니다. 따라서 실무에서는 데이터의 정합성을 보장하는 선(보통 3NF)에서 정규화를 마치거나, 성능 향상을 위해 의도적으로 중복을 허용하는 '반정규화'를 유연하게 섞어서 설계해야 합니다.

     

    [데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드[데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드
    [데이터베이스 핵심] "중복의 늪에서 탈출하라!" 정규화(1NF, 2NF, 3NF, BCNF) 완벽 정복 및 실전 가이드