데이터베이스 정규화(Normalization) 핵심 완벽정리
데이터베이스를 설계할 때, 마치 잘 정리된 도서관처럼 데이터를 체계적으로 관리하고 싶다면 '정규화(Normalization)'라는 개념을 반드시 알아야 합니다. 정규화는 데이터의 중복을 최소화하고, 데이터의 일관성과 무결성을 확보하여 보다 효율적이고 안정적인 데이터베이스를 만드는 과정입니다.
오늘은 이 정규화가 무엇인지, 그리고 각 단계별로 어떻게 진행되는지 쉽고 명확하게 알아보겠습니다!
1. 정규화(Normalization), 왜 필요할까요?
정규화의 핵심 목표는 "데이터 중복을 제거하여 데이터 불일치 위험을 줄이는 것"입니다. 데이터가 여러 곳에 중복되어 저장되면, 한 곳에서 수정이 일어났을 때 다른 곳의 데이터는 변경되지 않아 데이터가 어긋나는 '이상 현상(Anomaly)'이 발생할 수 있습니다.
정규화를 통해 얻을 수 있는 이점:
- 데이터 무결성 향상: 중복 데이터 제거로 데이터의 일관성과 정확성이 높아집니다.
- 저장 공간 효율화: 불필요한 데이터 중복이 사라져 저장 공간을 절약할 수 있습니다.
- 유지보수 용이성 증대: 데이터 구조가 단순하고 명확해져 수정 및 관리가 쉬워집니다.
- 이상 현상 방지: 데이터 삽입, 수정, 삭제 시 발생할 수 있는 문제를 예방합니다.
정규화는 여러 단계로 나뉘는데, 각 단계를 거치면서 테이블은 더욱 정제된 형태로 분리됩니다. 함께 살펴볼까요?
2. 제1정규형 (1NF): 모든 칸에는 하나의 값만!
제1정규형(First Normal Form, 1NF)은 정규화의 가장 기본 단계입니다. "테이블의 모든 컬럼(속성)은 원자값(Atomic Value)만을 가져야 한다"는 규칙입니다. 즉, 하나의 칸에 여러 개의 값이 쉼표(,) 등으로 구분되어 들어가 있거나, 반복되는 그룹이 있어서는 안 됩니다.
예시: 학생 연락처 테이블 (정규화 전)
학번 | 이름 | 연락처 |
---|---|---|
1001 | 김철수 | 010-1111-1111, 02-123-4567 |
1002 | 박영희 | 010-2222-2222 |
위 테이블에서 김철수 학생의 '연락처' 컬럼에는 두 개의 전화번호가 하나의 문자열로 들어가 있습니다. 이는 원자값 규칙에 위배됩니다.
제1정규화 진행 후:
학번 | 이름 | 연락처 |
---|---|---|
1001 | 김철수 | 010-1111-1111 |
1001 | 김철수 | 02-123-4567 |
1002 | 박영희 | 010-2222-2222 |
이렇게 각 연락처를 별도의 행으로 분리하여 모든 컬럼이 원자값을 갖도록 만들면 제1정규형을 만족합니다. (이름이 중복되지만, 이는 다음 단계에서 고려될 수 있습니다.)
3. 제2정규형 (2NF): 부분적 종속은 NO!
제2정규형(Second Normal Form, 2NF)은 테이블이 제1정규형을 만족하고, 기본키(Primary Key)의 일부에만 종속되는 컬럼(부분 함수 종속)이 없어야 한다는 규칙입니다. 이 규칙은 기본키가 여러 컬럼으로 구성된 복합키(Composite Key)일 때 의미가 있습니다.
"모든 일반 속성(키가 아닌 속성)은 기본키 전체에 완전하게 종속되어야 한다."
예시: 수강 신청 테이블 (제1정규형 만족, 제2정규형 불만족) 기본키: (학생ID, 과목코드)
학생ID | 과목코드 | 성적 | 과목명 |
---|---|---|---|
S100 | C01 | A+ | 데이터베이스 |
S100 | C02 | B0 | 운영체제 |
S200 | C01 | A0 | 데이터베이스 |
여기서 '성적'은 (학생ID, 과목코드) 전체에 의해 결정됩니다. 하지만 '과목명'은 '과목코드'만 알아도 결정될 수 있습니다. 즉, '과목명'은 기본키의 일부인 '과목코드'에 부분적으로 종속되어 있습니다.
제2정규화 진행 후:
수강 테이블 (기본키: 학생ID, 과목코드)
학생ID | 과목코드 | 성적 |
---|---|---|
S100 | C01 | A+ |
S100 | C02 | B0 |
S200 | C01 | A0 |
과목 테이블 (기본키: 과목코드)
과목코드 | 과목명 |
---|---|
C01 | 데이터베이스 |
C02 | 운영체제 |
이렇게 테이블을 분리하면 '과목명'은 '과목코드'에 완전하게 종속되고, 중복도 줄어듭니다.
4. 제3정규형 (3NF): 이행적 종속도 제거!
제3정규형(Third Normal Form, 3NF)은 테이블이 제2정규형을 만족하고, 기본키가 아닌 다른 일반 컬럼에 의해 결정되는 컬럼(이행적 함수 종속)이 없어야 한다는 규칙입니다.
"A → B 이고 B → C 일 때, A → C 가 성립하는 관계 (단, B는 후보키가 아님)를 제거한다."
예시: 직원 정보 테이블 (제2정규형 만족, 제3정규형 불만족) 기본키: 직원ID
직원ID | 직원명 | 부서코드 | 부서명 | 부서위치 |
---|---|---|---|---|
E001 | 홍길동 | D01 | 인사팀 | 본관3층 |
E002 | 임꺽정 | D02 | 개발팀 | 별관2층 |
E003 | 장보고 | D01 | 인사팀 | 본관3층 |
위 테이블에서 직원ID → 부서코드 이고, 부서코드 → (부서명, 부서위치) 관계가 성립합니다. 즉, '부서명'과 '부서위치'는 기본키인 '직원ID'에 직접 종속된 것이 아니라, '부서코드'를 거쳐 간접적으로(이행적으로) 종속됩니다. 만약 '인사팀'의 위치가 변경되면, 인사팀 소속 모든 직원의 데이터를 수정해야 하는 번거로움이 생깁니다.
제3정규화 진행 후:
직원 테이블 (기본키: 직원ID)
직원ID | 직원명 | 부서코드 |
---|---|---|
E001 | 홍길동 | D01 |
E002 | 임꺽정 | D02 |
E003 | 장보고 | D01 |
부서 테이블 (기본키: 부서코드)
부서코드 | 부서명 | 부서위치 |
---|---|---|
D01 | 인사팀 | 본관3층 |
D02 | 개발팀 | 별관2층 |
테이블을 분리하여 이행적 종속을 제거하면, 부서 정보 변경 시 '부서 테이블'만 수정하면 됩니다.
5. BCNF (Boyce-Codd 정규형): 모든 결정자는 후보키로!
BCNF(Boyce-Codd Normal Form)는 제3정규형보다 좀 더 엄격한 정규형입니다. "테이블의 모든 결정자(Determinant)가 후보키(Candidate Key)여야 한다." 결정자는 다른 속성의 값을 유일하게 결정하는 속성 또는 속성의 집합을 의미합니다.
제3정규형을 만족하더라도, 여러 후보키가 존재하고 이들이 서로 중첩되는 복잡한 경우 BCNF를 만족하지 못할 수 있습니다.
예시: 특강 수강 정보 테이블 (제3정규형 만족, BCNF 불만족) 가정:
- 학생은 여러 특강을 수강할 수 있다.
- 교수는 하나의 특강만 담당한다. (즉, 교수 → 특강명)
- 하나의 특강은 여러 교수가 담당할 수 없다.
- 후보키: (학생ID, 특강명) 또는 (학생ID, 교수명)
학생ID | 특강명 | 교수명 |
---|---|---|
S100 | DB특강 | 김교수 |
S100 | 알고리즘특강 | 박교수 |
S200 | DB특강 | 김교수 |
S300 | 알고리즘특강 | 박교수 |
위 테이블에서 (학생ID, 특강명) → 교수명 이고, (학생ID, 교수명) → 특강명 입니다. 둘 다 후보키입니다. 그런데 '교수명 → 특강명' 이라는 함수 종속성이 존재합니다. 여기서 '교수명'은 후보키가 아닙니다 (학생ID와 결합해야 후보키가 됨). 이것이 BCNF 위반입니다. 만약 김교수가 DB특강 대신 AI특강을 맡게 되면, S100과 S200의 특강명도 함께 수정해야 합니다.
BCNF 정규화 진행 후:
수강신청 테이블 (기본키: 학생ID, 교수명)
학생ID | 교수명 |
---|---|
S100 | 김교수 |
S100 | 박교수 |
S200 | 김교수 |
S300 | 박교수 |
교수특강 테이블 (기본키: 교수명)
교수명 | 특강명 |
---|---|
김교수 | DB특강 |
박교수 | 알고리즘특강 |
이렇게 분리하면 '교수명'이 '교수특강' 테이블의 기본키(후보키)가 되어 BCNF를 만족합니다.
정규화, 항상 완벽할까요? (반정규화의 등장)
정규화는 데이터 중복을 줄이고 일관성을 높이는 강력한 방법이지만, 너무 과도하게 진행하면 테이블이 지나치게 많이 분리됩니다. 이로 인해 데이터를 조회할 때 여러 테이블을 JOIN 해야 하므로 성능이 저하될 수 있습니다.
이런 경우, 때로는 반정규화(Denormalization)를 통해 의도적으로 중복을 허용하거나 테이블을 통합하여 성능을 향상시키기도 합니다. 반정규화는 정규화의 원칙을 거스르는 것이므로, 데이터 일관성이 깨질 위험과 성능 향상의 이점을 신중하게 고려하여 결정해야 합니다.
마무리: 깔끔한 데이터 설계를 위한 첫걸음
정규화는 데이터베이스 설계의 기본기를 다지는 중요한 과정입니다. 각 정규형의 의미를 이해하고 적용함으로써, 우리는 더욱 견고하고 효율적인 데이터베이스 시스템을 구축할 수 있습니다. 물론, 실제 상황에서는 정규화 수준과 성능 사이의 균형을 맞추는 지혜도 필요합니다.
오늘 배운 정규화 지식을 바탕으로 여러분의 데이터베이스를 더욱 빛나게 만들어보세요!