모던지 / SQL 개발자 / 데이터 모델링 5강. 정규화와 반정규화

데이터 모델링 5강. 정규화와 반정규화

정규화는 성능을 포기하고 정합성을 사는 일이 아닙니다. 대부분의 조회에서는 정규화가 성능까지 같이 벌어 줍니다.

풀고 시작

문제 1. 주식별자가 학번과 과목코드인 수강 엔터티에 학생이름이 들어 있습니다. 학생이름은 학번만으로 결정됩니다. 이 상태를 해소하는 정규화 단계는?
복합 주식별자의 일부에만 종속된 속성을 떼어 내는 것이 제2정규화입니다. 제1정규형은 다중값을 없애는 단계이고, 제3정규형은 키가 아닌 속성 사이의 종속을 없애는 단계라 상황이 다릅니다.

함수적 종속이라는 한 문장

정규화를 외우려 들면 정규형 이름 대여섯 개가 뒤섞입니다. 그런데 정규화의 재료는 딱 하나, 함수적 종속(functional dependency)입니다. 속성 A의 값이 정해지면 속성 B의 값도 하나로 정해질 때, B는 A에 함수적으로 종속된다고 말합니다. 주민등록번호가 정해지면 생년월일이 정해지죠. 반대는 성립하지 않습니다.

정규화는 이 종속 관계를 보고 "이 속성은 이 키에 딸린 것이 맞는가"를 계속 묻는 작업입니다. 딸린 곳이 아닌 자리에 앉아 있는 속성을 제 자리로 옮기는 것이 전부입니다. 그리고 제 자리로 옮기면 자연히 중복이 사라지고, 1강에서 본 삽입과 갱신과 삭제 이상 현상이 함께 사라집니다.

세 단계를 한 줄씩

제1정규형은 모든 속성이 원자값을 갖는 상태입니다. 한 칸에 값이 여러 개 들어 있거나 반복되는 그룹이 있으면 여기서 걸립니다. 3강에서 다중값 속성을 별도 엔터티로 분리한다고 했던 그 이야기입니다.

제2정규형은 제1정규형이면서 부분 함수적 종속이 없는 상태입니다. 주식별자가 여러 속성으로 이뤄졌을 때만 문제가 생깁니다. 수강 엔터티의 키가 학번과 과목코드인데 학생이름이 학번만으로 결정된다면, 학생이름은 키의 일부에만 딸려 있습니다. 이 속성을 학생 엔터티로 옮기는 것이 제2정규화입니다. 그래서 주식별자가 단일 속성이면 제2정규형 위반은 원리상 발생하지 않습니다.

제3정규형은 제2정규형이면서 이행 함수적 종속이 없는 상태입니다. 키가 아닌 속성이 다른 키가 아닌 속성을 결정하는 상황이죠. 사원 엔터티에 부서코드와 부서명이 같이 있으면, 사번이 부서코드를 결정하고 부서코드가 부서명을 결정합니다. 부서명은 사번에 직접 딸린 것이 아니라 부서코드를 거쳐 딸려 있으니 부서 엔터티로 옮겨야 합니다.

정규형 없애는 것 알아보는 신호
제1정규형 다중값과 반복 그룹 한 칸에 값이 여러 개 보인다
제2정규형 부분 함수적 종속 복합 키의 일부만으로 결정되는 속성이 있다
제3정규형 이행 함수적 종속 키가 아닌 속성이 다른 속성을 결정한다
보이스코드 정규형 후보키가 아닌 결정자 결정자인데 후보키가 아닌 속성이 있다

보이스코드 정규형은 제3정규형을 조금 더 조인 것입니다. 어떤 속성이 다른 속성을 결정한다면 그 결정자는 후보키여야 한다는 조건이죠. 후보키가 여러 개 있고 서로 겹치는 특수한 상황에서만 문제가 되므로, 시험에서는 정의만 정확히 기억해 두면 충분합니다.

정규화가 성능을 해친다는 오해

"정규화하면 조인이 늘어 느려진다"는 말을 자주 듣습니다. 절반만 맞습니다.

정규화하면 테이블 하나에 담긴 컬럼 수가 줄어들고, 그러면 같은 블록에 더 많은 행이 들어갑니다. 그 결과 특정 컬럼만 훑는 조회에서는 읽어야 할 블록 수가 줄어 오히려 빨라집니다. 게시판 목록을 뽑을 때 본문이 다른 테이블에 있으면 목록 조회가 가벼워지는 것이 이 원리죠.

느려지는 쪽은 여러 테이블의 값을 한 번에 다 봐야 하는 조회입니다. 조인이 늘고, 조인 대상이 크면 비용이 커집니다. 즉 정규화가 성능에 미치는 영향은 조회 패턴에 따라 방향이 갈립니다. 시험에서 "정규화는 항상 성능을 저하시킨다"는 보기가 나오면 그것이 틀린 보기입니다.

반정규화는 마지막에 꺼내는 카드입니다

반정규화(denormalization)는 정규화된 모델을 성능이나 개발 편의를 위해 일부러 되돌리는 일입니다. 중요한 것은 순서입니다. 정규화를 먼저 하고, 성능 문제가 실제로 확인된 자리에만 반정규화를 적용합니다. 처음부터 반정규화된 모델을 그리면 무엇을 왜 되돌렸는지 아무도 알 수 없게 됩니다.

반정규화의 방법은 대상에 따라 나뉩니다. 테이블 반정규화로는 자주 함께 조회되는 테이블을 병합하거나, 반대로 큰 테이블을 행 단위나 컬럼 단위로 분할하거나, 집계용 테이블을 새로 추가합니다. 컬럼 반정규화로는 조인을 없애기 위해 중복 컬럼을 두거나, 파생 컬럼을 미리 계산해 둡니다. 관계 반정규화로는 조인 경로를 줄이려고 중복 관계선을 추가합니다.

값을 지불한다는 사실을 잊지 않는 것이 핵심입니다. 반정규화로 얻는 것은 조회 속도이고, 잃는 것은 정합성을 지키는 비용입니다. 중복 컬럼을 두었다면 원본이 바뀔 때 그 컬럼도 반드시 함께 바꿔 주는 장치가 있어야 합니다. 그 장치를 만들지 않은 반정규화는 성능 개선이 아니라 시간을 두고 터지는 데이터 오류입니다.

다음 강에서는 이렇게 나눈 모델이 조인과 트랜잭션과 NULL에서 어떻게 드러나는지 봅니다.

인출 문제

문제 1. 제3정규형 위반에 해당하는 상황은?
제3정규형은 이행 함수적 종속을 없애는 단계입니다. 첫 번째는 제1정규형, 두 번째는 제2정규형 위반이고, 마지막은 보이스코드 정규형에서 다루는 상황입니다.
문제 2. 주식별자가 단일 속성인 엔터티에서 원리상 발생할 수 없는 정규형 위반은?
제2정규형 위반은 복합 키의 일부에만 종속되는 속성이 있을 때 생기므로 키가 하나면 성립하지 않습니다. 다중값 문제와 이행 종속 문제는 키가 하나여도 얼마든지 생깁니다.
문제 3. 정규화와 성능의 관계에 대한 설명으로 가장 적절한 것은?
정규화는 테이블을 가볍게 만들어 특정 컬럼만 읽는 조회를 빠르게 하기도 하고, 여러 테이블의 값을 함께 봐야 하는 조회를 느리게 하기도 합니다. 방향이 조회 패턴에 따라 갈리므로 항상 저하된다는 말은 틀립니다.
문제 4. 반정규화를 적용할 때의 원칙으로 옳지 않은 것은?
처음부터 반정규화된 모델은 무엇을 왜 되돌렸는지 근거를 남기지 못해 이후 유지보수가 어려워집니다. 반정규화는 정규화된 모델을 기준으로, 문제가 확인된 자리에만 값을 치르고 적용하는 예외 처리입니다.

더 풀기

출제기준의 세세항목을 따라 이 강의 범위에서 새로 낸 문제입니다. 모의고사도 여기에서 뽑습니다.

묶음 1

문제 1. 함수적 종속을 가장 잘 설명한 것은?
사원번호가 정해지면 사원 이름이 하나로 정해집니다. 이때 이름은 사원번호에 함수적으로 종속됩니다. 값이 같다는 것과는 전혀 다른 개념입니다.
문제 2. 부분 함수 종속을 가장 잘 설명한 것은?
부분 종속은 복합키가 있을 때만 생깁니다. 일반 속성에 종속되는 것은 이행 종속입니다.
문제 3. 이행 함수 종속을 가장 잘 설명한 것은?
사원번호가 부서코드를 정하고 부서코드가 부서명을 정한다면 부서명은 사원번호에 간접적으로 종속됩니다. 이런 구조를 3정규형에서 걷어냅니다.
문제 4. 제1정규형이 요구하는 것은?
1정규형은 원자값을 요구합니다. 부분 종속 제거는 2정규형, 이행 종속 제거는 3정규형, 결정자 조건은 보이스코드 정규형입니다.
문제 5. 제2정규형을 만족하려면 무엇이 없어야 하나요?
2정규형은 부분 종속을 없앱니다. 기본키가 단일 속성이면 부분 종속이 생길 수 없어 1정규형이면 자동으로 2정규형입니다.
문제 6. 기본키가 단일 속성인 릴레이션이 1정규형을 만족한다면 몇 정규형까지 자동으로 만족하나요?
부분 종속은 복합키가 있어야 생기므로 단일키면 2정규형은 자동입니다. 이행 종속은 여전히 있을 수 있어 3정규형은 별도로 확인해야 합니다.
문제 7. 제3정규형을 만족하려면 무엇이 없어야 하나요?
3정규형은 일반 속성끼리 서로를 결정하는 관계, 즉 이행 종속을 걷어냅니다.
문제 8. 보이스코드 정규형을 가장 잘 설명한 것은?
보이스코드 정규형은 3정규형을 강화한 것으로, 후보키가 아닌 속성이 다른 속성을 결정하는 상황을 없앱니다. 다중값 종속은 4정규형, 조인 종속은 5정규형의 주제입니다.
문제 9. 제4정규형이 다루는 문제는?
4정규형은 서로 무관한 두 다중값 속성이 한 릴레이션에 섞여 불필요한 조합이 생기는 문제를 다룹니다.
문제 10. 정규화의 목적으로 가장 알맞은 것은?
정규화의 목적은 일관성입니다. 테이블 수는 오히려 늘고 조인도 늘지만 값이 어긋날 자리를 없앱니다.

묶음 2

문제 1. 갱신 이상 가운데 삽입 이상을 가장 잘 설명한 것은?
아직 수강생이 없는 과목을 등록하려는데 수강 정보가 함께 있어야만 행을 만들 수 있다면 삽입 이상입니다. 나머지는 삭제 이상과 수정 이상의 설명입니다.
문제 2. 삭제 이상의 예로 가장 알맞은 것은?
한 행에 여러 주제가 섞여 있으면 한 주제를 지울 때 다른 주제도 사라집니다. 이것이 삭제 이상입니다.
문제 3. 수정 이상이 생기는 근본 원인은?
부서명이 사원마다 저장되어 있으면 부서명 하나를 바꿀 때 모든 사원 행을 함께 고쳐야 하고 하나라도 빠지면 값이 어긋납니다.
문제 4. 주문번호와 상품번호가 복합키인 주문상세 테이블에 상품명이 들어 있다면 어떤 종속 문제가 있나요?
상품명은 상품번호만으로 결정되므로 복합키의 일부에만 종속됩니다. 이것이 부분 종속이고 2정규형 위반입니다.
문제 5. 사원 테이블에 사원번호와 부서코드와 부서명이 있다면 어떤 정규형을 위반한 것인가요?
부서명은 부서코드에 종속되고 부서코드는 사원번호에 종속됩니다. 기본키가 아닌 속성 사이의 종속이므로 3정규형 위반입니다.
문제 6. 정규화를 진행하면 일반적으로 나타나는 변화로 가장 알맞은 것은?
주제별로 쪼개므로 테이블은 늘고 조인은 늘어납니다. 대신 행이 짧아져 한 번에 읽는 양이 줄어드는 이점도 생깁니다.
문제 7. 정규화가 항상 성능을 나쁘게 한다는 말이 오해인 이유로 가장 알맞은 것은?
정규화는 조회에서 조인 비용을 늘리지만 저장과 갱신에서는 유리합니다. 성능은 조회와 갱신을 함께 보아야 판단할 수 있습니다.
문제 8. 반정규화를 검토하기 전에 먼저 시도해야 할 것으로 가장 알맞은 것은?
반정규화는 일관성을 대가로 지불하는 선택이라 마지막에 꺼냅니다. 되돌리기 쉬운 수단부터 차례로 시도하는 것이 순서입니다.
문제 9. 반정규화의 대상으로 보기 어려운 것은?
반정규화는 중복을 의도적으로 두어 조회를 줄이는 기법입니다. 기본키를 없애는 것은 무결성을 포기하는 일이라 반정규화의 수단이 아닙니다.
문제 10. 반정규화를 적용한 뒤 반드시 함께 마련해야 하는 것은?
중복을 만들었으면 어긋날 것을 전제해야 합니다. 갱신 시점과 불일치 점검 방법을 정해 두지 않은 반정규화는 사고를 예약해 둔 것과 같습니다.

묶음 3

문제 1. 테이블 수직 분할을 하는 이유로 가장 알맞은 것은?
수직 분할은 컬럼을 기준으로 나눕니다. 행 수가 많아 나누는 것은 수평 분할입니다.
문제 2. 테이블 수평 분할이 효과적인 상황으로 가장 알맞은 것은?
수평 분할은 행을 기준으로 나눕니다. 조회가 특정 구간에만 몰린다면 나머지를 읽지 않아도 되어 효과가 큽니다.
문제 3. 두 테이블을 병합하는 반정규화가 유리한 경우로 가장 알맞은 것은?
늘 함께 읽히고 잘 바뀌지 않는다면 합쳐서 조인을 없애는 이득이 큽니다. 갱신이 잦으면 중복 유지 비용이 이득을 넘어섭니다.
문제 4. 통계 테이블을 따로 만드는 것을 반정규화로 보는 이유는?
집계 결과는 원본으로부터 언제든 다시 만들 수 있는 값입니다. 그것을 저장하는 것은 계산 비용과 일관성을 맞바꾸는 반정규화입니다.
문제 5. 정규화 과정에서 릴레이션을 분해할 때 반드시 지켜야 하는 성질은?
무손실 분해가 정규화의 전제입니다. 다시 붙였을 때 없던 행이 생기거나 있던 정보가 사라지면 그 분해는 잘못된 것입니다.
문제 6. 과목과 강사와 교재를 한 테이블에 담았더니 강사와 교재가 서로 무관하게 여러 개씩 붙어 모든 조합이 저장되고 있다면 어떤 정규화가 필요한가요?
서로 독립적인 두 다중값 속성이 한 릴레이션에 있으면 불필요한 조합이 생깁니다. 이것이 다중값 종속이고 4정규형으로 분해합니다.
문제 7. 다음 중 정규화로 해결되지 않는 문제는?
정규화는 중복에서 오는 이상 현상을 다룹니다. 정렬 성능은 인덱스와 질의 설계로 다루는 별개의 문제입니다.
문제 8. 반정규화를 결정할 때 가장 먼저 확인해야 할 자료는?
어디가 얼마나 자주 읽히고 얼마나 자주 바뀌는지를 모르면 무엇을 중복시킬지 정할 수 없습니다. 근거 없는 반정규화는 손해만 남깁니다.
문제 9. 정규화를 충분히 하지 않은 채 반정규화부터 적용하면 생기는 문제로 가장 알맞은 것은?
반정규화는 정규화된 모델을 기준으로 되돌리는 작업입니다. 기준이 없으면 나중에 어디를 고쳐야 할지 알 수 없습니다.
문제 10. 다음 설명 중 옳은 것은?
반정규화는 실패가 아니라 근거를 갖춘 선택입니다. 다만 그 대가가 무엇인지 알고 관리 방법을 함께 마련해야 합니다.

이전: 4강 관계와 식별자 · 다음: 6강 조인, 트랜잭션, 그리고 NULL

모던지 · 궁금하면 모던지 GitHub · 2026-09-10