데이터 인사이트

데이터 전문가 칼럼
데이터 전문가가 전하는 데이터 노하우

노찬형의 제로에서 시작하는 데이터 모델링 시즌II (최종회) : 모델링을 잘할 수 있는 조건 ‘정규화’

작성자
관리자
작성일
2020-08-28 18:24
조회
1355

노찬형의 제로에서 시작하는 데이터 모델링 시즌II (최종회)


모델링을 잘할 수 있는 조건 ‘정규화’

필자: 노찬형
대학에서 소프트웨어공학을 전공했으며 개발자로 사회 생활을 시작했다. 사회 생활 10년을 넘기고 시작했던 DB 공부가 프로그래머로서 자신을 분명하게 되돌아볼 수 있는 기회를 주었다. 사회 초년생 또는 대학생에게 도움이 되는 데이터 모델링 글을 쓰고 싶은 게 그의 작은 바람이다.
pemaker@gmail.com
?

주경야독하는 이들을 위해

우연한 일이 계기가 돼 필자는 DB와 데이터 모델링을 글로 정리할 수밖에 없는 상황에 맞닥뜨렸다. 필자는 2012년부터 2013년까지 한 대학에서 DB 강의를 했다. 강의를 요청받았을 때, 어떻게 해야 할지 난감했다. 필자가 맡은 반은 낮에는 일하고 저녁에 공부하는 학생들로 구성돼 있었다. 일반 대학생들처럼 많은 시간을 공부에 쓸 수 없는 학생들에 DB를 알려줘야 했다. 어떻게 하면 그들에게 작으나마 도움이 될까 하고 고민하던중 시중 교재 대신, 필자가 직접 강의 자료를 만들어 보면 좋겠다는 생각을 하기에 이르렀다.

물론 시중의 책이 부족해서 그런 것은 아니다. 필자가 자료를 직접 만들어 쓰면, 일반 책으로 했을 때보다 더 쉽게 소개할 수 있을 것 같아서 그랬다. 누가 보더라도 이해하기 쉽게 전달하겠다는 목표로 강의 자료를 만들기 시작했다. 2년 넘게 강의 자료를 준비하다 보니, DB의 기초와 데이터 모델링의 기초에 대한 내용을 어느 정도 만들어 낼 수 있었다.

학생들이 강의자료를 요청하면 줬다. 하지만 설명이 없는 프레젠테이션 문서라서 아쉬웠다. 설명이 추가되면 학생들이 예습/복습을 할 때도 훨씬 좋을 텐데…. 배웠거나 배울 학생들을 위해 프레젠테이션 문서를 글로 정리하기 시작했다. 말보다 글로 정리하는 게 더 어렵다는 걸 실감하는 순간의 연속이었다.

‘하늘 아래 새로운 건 없다’는 말처럼 필자의 강의 자료 역시 인식하든 못하든 수많은 자료와 가르침을 받았던 결과물들이다. 물론 보고 들었던 이론을 개발 현장에서 적용·확인하는 과정을 거친, 경험의 산물이다. 앞으로 몇 회에 걸쳐 ‘제로에서 시작하는 데이터 모델링’ 연재를 하겠다고 용기를 내보았다. 독자 여러분과 함께 쓴다는 생각으로 수많은 의견이나 접근 방법을 댓글 또는 이메일로 받을 수 있었으면 좋겠다.
?

지난 연재에서 식건자에 대해 알아보았다. 식별자란 여러 개의 데이터(인스턴스)에서 각각의 데이터(인스턴스)를 구분할 수 있는 속성의 조합임을 다시 한번 떠올리며, 연재의 마지막 주제인 정규화에 대해 알아본다.

?

? 정규화

정규화(normalization)는 데이터 모델링의 핵심이자 꽃이다. 정규화의 목적은 관계형 DB 기반의 모든 프로젝트에서 중복 없는(no redundancy) 상태의 좋은 모델을 만들기 위해서다.

식별자와의 종속성, 즉 함수종속을 기반으로 유사한 속성들을 모으고 분리하는 형태로 정규화한다. 정규화를 잘하면 모델링도 잘할 수 있다는 말처럼, 정규화는 모델링에서 꼭 해야 하는 부분이다. ‘중복이 없는 상태’는 앞선 연재에서 여러 번 소개했으니 어느 정도 감을 잡았을 것이다.

함수종속(functional dependency)은 특별히 소개한 적도 없어서 다소 생소하게 여겨질 것이다. 함수종속이 나오는 이유는 코드(E.F.Codd) 박사가 수학의 집합 개념을 기반으로 데이터 모델링의 개념을 정립했기 때문이다.

함수종속이란 데이터의 종속성(data dependency)에 관한 것이다. 집합에는 집합을 대표하는 속성이 존재한다. 종속성이란 바로 이 대표 속성과 나머지 속성상의 연관 관계를 말한다.

한국 사람이라면 이름, 주민등록번호, 키, 몸무게, 성별, 핸드폰번호 등 많은 속성을 갖고 있다. 이 가운데 이름이나 주민등록번호가 한국인임을 구분해주는 어느 한 사람의 속성이다. 주민등록번호가 대표적인 속성으로, 특정인을 다른 사람과 구별해주는 역할을 한다. 나머지 속성들은 이 주민등록번호에 종속돼 있다.

이것을 다른 말로 바꿔보면, A 속성 값이 B 속성 값을 유일하게 식별할 수 있는 기준이라면 B 속성은 A 속성에 함수적으로 종속됐다고 한다.

본 연재에서 정규화의 기본 개념을 이해하고 자세한 사항은 김기창의 [관계형 데이터 모데링 프리미디어 가이드](위즈덤마인드 간) 등을 참고하여 심화학습하기 바란다.

? 정규화의 종류

정규화는 제1정규화, 제2정규화, 제3정규화, 보이스-코드정규화(BCNF), 제4정규화, 제5정규화 등이 있다. 여기서는 1정규화에서 3정규화까지는 쉽게 습득할 수 있으므로 제1정규화부터 제3정규화까지 알아본다. 본 연재에서 제5정규화 심지어 제6정규화까지도 소개할 수 있지만, 기본을 먼저 다지면 나머지를 학습하는 힘이 생길 것이다.

앞 연재에서 좋은 모델은 완전성(누락된 업무가 없음), 유일성(데이터 중복이 없음), 업무 적용성(모든 업무와 규약을 담고 있어야 함), 유연성(비즈니스 모델이 변경돼도 가능하면 모델이 변경되지 않아야 함)과 함께 단순하면서도 엘레강스해야 한다고 소개했다.

좋은 모델링을 위해 정규화를 해야 하며, 이를 통해 비즈니스와 데이터 성격에 맞는 엔터티가 도출된다. 비즈니스와 데이터 성격에 맞는 엔터티가 도출되면 확장성이 좋은 모델이 된다.

또한 정규화는 이상(anomaly) 현상을 최소화하는 작업이기도 하다. 데이터 중복은 이상현상을 발생시키는 데 이상현상이 없어야 데이터 품질을 높일 수 있다. 일부 전문가는 ‘정규화 단계를 포기하면 모델링을 수행했다고 할 수 없다. 모델러라면 반드시 정규화를 해야 한다’고 강조한다. 그만큼 정규화는 모델링에 있어서 중요한 부분이다.

그렇다면 1에서 3까지의 정규화, BCNF, 4에서 5까지의 정규화를 전부 해야 할까? 3정규화까지만 하면 된다는 의견도 있고 안 해도 된다는 의견도 있다. 정규화는 업무 요건에 따라 함수종속성을 따져 데이터 중복을 제거하는 작업이므로 몇 정규화까지만 수행해야 하는지 논쟁은 의미가 없다. 필요하다면 5정규화가 아닌 그 이상이라도 해야 한다.

일반적으로 1에서 3정규화가 정규화의 대부분을 차지하므로 3정규화까지만 하면 된다는 의견도 있다. 하지만 BC정규화, 4정규화, 5정규화를 위반하는 경우도 종종 있으므로 나머지도 알고 있어야 한다.

이제부터 1부터 3정규화까지 알아보자. ‘정규화’라는 말과 ‘정규형’이라는 말이 있다. 정규화한 결과를 정규형(normal form)이라 한다.

정규화는 1, 2, 3 순서대로 하지 않는다. 설명하기 쉽게 제1정규화부터 이야기하는 것이지, 모델러들이 정규화할 때는 제1에서 제3, 심지어는 제5정규화까지 동시에 한다. 운전할 때와 비슷하다. 운전할 때, 브레이크에서 발을 떼는 순간 엑셀러레이터를 밟으면서 핸들을 조작하면서 앞뒤와 옆을 보듯이 모델링의 정규화도 정해진 순서에 따라 진행하지 않는다.

? 결정자와 종속자

정규화에 대한 이야기를 하기 전에 결정자(determinant)와 종속자(dependant) 대해 알아보고 가자. 이 이야기를 하는 이유는 혹 대학생 때 DB 관련 강의를 수강했거나 정보처리기사 시험을 봤던 사람이라면 ‘두부이겨다줘’라고 외웠던 기억을 갖고 있을 것이다.

각 정규화의 정의를 앞 글자만 따서 외울 때 쓰던 용어다. 제일 앞의 ‘두’는 원래 ‘도(도메인의 원?행함수종속제거가 나온다.

함수와 종속제거라는 말이 나오는데, 이는 함수와 종속 개념을 정확히 알아야 정규화할 수 있다는 말이다. 우리가 흔히 쓰는 것이 아니므로 어렵게 느껴지겠지만, 너무 걱정하지 말고 하나씩 이해하고 넘어가면 된다. 결정자는 속성 간 종속성을 분석할 때 기준이 되는 값을 말한다. 이 결정자에 의해 정해질 수 있는 값을 종속자라고 한다.

속성 Y가 속성 X에 의해 함수적으로 종속됐다는 말은, 속성 X값을 이용해 속성 Y값을 유일하게 식별할 수 있다는 뜻이다. 앞서 소개한 여러분의 키와 주민등록번호를 보면, 키는 종속자, 주민등록번호는 결정자다. 다시 말하면 결정자는 식별자, 종속자는 속성을 의미한다.

이를 X→Y 또는 y=f(x)라고 표현한다.


[그림 1] 결정자와 종속자
결정자는 종속자의 값을 결정한다. [그림 1]의 주문금액 엔터티는 무엇으로 결정되는가를 보면 고객번호와 주문일시에 의해 결정되는 것을 알 수 있다. 성명은 고객번호에 의해 결정되는 것을 알 수 있다.

고객 엔터티에서 보면 고객번호가 결정자가 되며, 나머지 속성이 종속자가 된다. 이것을 반대로 말하면 식별자(결정자)로 데이터를 찾으면 딱 한 건이 나와야 한다고 할 수 있다. 만약에 2건이 나온다면 결정자가 아니다. 우리의 이름이 결정자가 될 수 없는 이유는 이 때문이다.

결국 결정자와 종속자는 앞서 소개한 식별자를 정의하는 것과 같다. 결정자는 식별자, 종속자는 속성이라고 생각하면 함수종속을 쉽게 이해할 수 있을 것이다.

? 정규화 실무

1) 제1정규화

제1정규화는 엔터티 안의 모든 속성은 반드시 1개 값을 가져야 한다는 뜻이다. 이를 도메인의 원자성이라고도 하는데, 속성이 하나의 값을 가져야 한다는 뜻이다. 원자성 또는 하나의 값을 가져야 한다는 뜻을 조금 더 알아보자.

제1정규화를 하려면 다가속성(multivalued attributes)과 복합속성(composite attribute)을 알아둘 필요가 있다.


[그림 2] 고객정보 정규형을 위반한 릴레이션: 다가속성
다가속성은 한 속성에 여러 값이 들어 있는 것을 말한다. [그림 2]를 보면 고객의 ‘취미’라는 하나의 속성에서 1개 이상의 값을 관리하는 것을 볼 수 있다. 현실에서는 이렇게 많이 관리하더라도 데이터 영역에서 좋지 않다. 이렇게 하나의 속성에 여러 값을 넣어서 관리하는 것이 제1정규화 위배의 다가속성에 해당한다.

데이터 모델링 관점에서 다가속성을 단일 값을 갖는 형태로 바꾸면 [그림 3]과 같다.


[그림 3] 제1정규화 릴레이션: 다가속성
[그림 3]은 [그림 2]의 제1정규화 위반인 다가속성을 해결한 한 것으로, 취미라는 속성에 하나의 값만 들어가도록 바꾼 것이다. 이것을 모델로 표현해 보면 [그림 4]와 같다.


[그림 4] 정규화 모델
[그림 4]의 왼쪽은 [그림 2]의 모델이고, 오른쪽은 [그림 2]를 정규화한 [그림 3] 모델이다. 이와 같이 제1정규화 위반 중 하나인 다가속성 문제는 [그림 4]와 같이 분리함으로써 해결할 수 있다.

여기서 주의할 점은 [그림 4]의 왼쪽 모델과 엔터티 안의 ‘취미’라는 속성을 보면 아무런 문제가 없어 보인다. 그리고 취미 속성 안에 같은 종류의 여러 값을 갖고 있음은 알 수 없으므로 모델만 보지 말고 데이터를 꼭 확인해 봐야 한다.

다가속성과 비슷한 경우가 논리적으로 여러 값을 갖는 속성이 존재하는 엔터티다.


[그림 5] 논리적으로 여러 값을 갖는 엔터티
[그림 5] 모델을 보면 여러 개의 취미를 관리하기 위해 취미1, 취미2, 취미3이라는 속성을 만들어 관리하고 있다.

이 경우도 특별히 문제가 없어 보인다. 만약 취미를 3개 이상 관리해야 한다면, 속성에 취미4를 추가함으로써 요건을 만족할 수 있다. 하지만 관리해야 하는 취미가 늘어난다면, 계속 속성을 추가하는 모델 변경이 일어나야 하기 때문에 좋다고 말하기는 어렵다. 같은 성격의 데이터를 여러 속성으로 나열해 관리하는 것도 논리적으로는 여러 값을 관리하는 것이므로 이런 경우 역시 제1정규화를 위배한 사례다. [그림 4]의 오른쪽 모델과 같이 제1정규화를 해주는 것이 좋다.

데이터 모델의 정규화 이론에서는 [그림 4]의 오른쪽 모델과 같이 정규화해서 정규형을 만드는 것이 바람직하지만, 비즈니스 요건이 변화하지 않고 성능까지 고려하면 좋은 모델이 될 수 있으므로 비정규형으로 모델링할 수도 있다.

여기서 꼭 명심해야 할 점은, 정규화를 알고서 비정규형을 사용해야 하는 것이다. 단지 편하니까, 다들 그렇게 하니까라는 기준에 따라 비정규형을 사용하는 것은 지양해야 한다.

다음으로는 복합속성(composite attributes)이다. 복합속성은 하나의 속성이 여러 속성으로 분리될 수 있음을 말한다. 대표적인 예가 주소나 전화번호다. 온라인 쇼핑몰에서 물건을 주문하고 배송지 주소를 입력할 때를 생각해 보자. 기본 주소와 상세 주소를 나눠 입력할 것이다. 특정 온라인 서비스에서 회원 가입 시, 휴대전화번호를 하나의 필드에 입력하는 경우도 있고 000-0000-0000 형태로 나누어 넣는 경우가 있다.

회원을 관리할 때 휴대전화번호를 하나의 필드, 즉 속성으로 관리하는 것이 좋을지, 통신망식별번호-국번호-가입자 개별번호로 나눠 관리하는 것이 좋을지 생각해 보자.

제1정규화의 사상은 도메인의 원자성이다. 원자성이란 하나의 속성에 하나의 값만 관리하는 것이라고 소개했다. 또한 더 이상 분해할 수 없어야 한다. 전화번호 전체를 하나의 속성에 관리하면, 더 이상 분해할 수 없는 원자성을 만족했다고 판단하기 어렵다.

복합속성은 업무의 정의에 따라 그 원자성의 기준이 달라질 수 있다. 업무적으로 전화번호를 하나의 속성으로 관리하는 것으로 정의했다면, 전화번호는 복합속성이 아닌 원자성을 만족했다고 할 수 있다. 즉 원자성에 대한 판단 기준은 업무정의이므로 모델이나 데이터만 보고 판단해서는 안 된다.

제1정규화를 해야 하는 대상을 정리하면 다음과 같다.

- 다가속성일 때
- 유사한 속성이 반복적으로 사용될 때
- 복합속성이 사용될 때

제1정규화 위배는 주로 프로세스와 화면 종속적인 모델링에서 발생한다. 즉 화면에 보이는 모습대로 모델링하거나 하나의 로우(row)로 처리하려는 욕심에서 발생한다.

제1정규화를 위배하면 데이터의 재사용성??석과 집계), 효과적인 인덱스 구성의 어려움, 성능저하 가능성 증가, 정렬의 난이도 증가 등의 문제를 불러올 수 있다.

제1정규형을 위반한 경우, 즉 하나 이상의 값을 가진다면 다수의 값을 가질 수 있는 구조로 바꿔줌으로써 해결할 수 있다. 즉 해당 속성을 분리해 자식(하위) 엔터티를 생성해주면 된다.

2) 제2정규화

제2정규화는 부분 함수종속제거다.

모든 속성(식별자를 제외한 모든 속성)은 식별자에 완전 함수종속(fully functional dependency)이 돼야 한다. 일부 식별자에 종속(partial functional dependency)돼 있다면 제 2 정규형이 아니며 제2정규화를 위배한 것이다. 다시 말하면 제2정규화는 엔터티 내의 모든 속성은 식별자 전체에 직접 종속되게 하는 것이다.

완전함수종속, 부분함수종속, 부분함수종속제거 같은 말이 어렵지만, 제2정규화는 식별자 속성이 1개 이상인 경우에 발생한다. 식별자 이외의 일반속성이 어느 하나의 식별자 속성에만 속하는 경우를 제2정규화를 위반했다고 한다.

여기서 말하는 식별자는 의미상의 식별자들로서 본질식별자가 없다면 제2정규화 확인은 불가능하다. 인조식별자는 임의의 값이므로 종속성 확인이 불가능하다. 꼭 그런 것은 아니지만, 본질식별자의 도출 없이 인조식별자를 사용하면 제2정규화를 위반할 가능성이 매우 높다.


[그림 6] 제2정규화 위배 사례
[그림 6] 모델을 보면 식별자가 과목코드와 강사코드이며, 일반속성은 과목명·강사명·최초담당일자다.

위 모델을 자세히 보면, 과목과 강사 정보가 같이 존재하고 있음을 알 수 있다. 과목과 강사에 대한 정보와 속성들을 분류해볼 필요가 있다. 과목은 과목코드와 과목명으로, 강사는 강사코드와 강사명으로 구분할 수 있다. 이때 최초담당일자는 명확하지 않아 일단 제외하고 넘어가자.

이렇게 분류해보면, 과목명은 과목코드에만 종속돼 있고 강사코드와는 관계가 없다. 강사명은 강사코드에만 종속돼 있고, 과목코드와는 관계가 없음을 알 수 있다.

이와 같이 속성이 일부 식별자에 종속된 경우가 제2정규화를 위배한 것이다. 식별자 전체에 완전함수종속이 아닌 일부, 즉 부분함수종속이 발생한 것이다. 발생한 부분함수종속을 제거해주는 것이 제2정규화의 부분 함수종속제거다.


[그림 7] 제2정규화
[그림 6] 모델을 정규화하면 과목과 강사를 분리해, [그림 7]과 같이 과목 엔터티, 강사 엔터티, 과목별강사의 릴레이션 엔터티로 모델링할 수 있다. 이렇게 제2정규화를 하고 나니 [그림 6]의 최초담당일자도 명확해졌다.

제2정규화 위배는 본질식별자의 정의없이 인조식별자를 도출해 사용하거나, 부모의 속성을 자식이 갖고 있는 경우에 주로 발생한다. 제2정규화를 위배하면 데이터 값을 하나로 맞출 수 없어 정합성이 훼손되거나, 유지에 많은 리소스가 투입될 가능성이 있다.

3) 제3정규화

제3정규화는 이행함수종속 제거다. 제3정규화는 제2정규화를 하지 안고서는 불가능하다. 모델링에는 순서가 없기는 하지만 제3정규화를 위해서는 꼭 제2정규화가 돼야 한다.

모델링을 하고 보면, 어느 일반속성이 다른 일반속성에 종속되는 경우, 즉 일반속성 간에 종속성이 존재하는 경우가 있다. 이는 제3정규화를 위반한 것으로 이행함수종속이라고 한다.

이행함수종속 제거란 식별자가 아닌 모든 속성은 서로 종속되지 않도록 하는 것이다. 이것이 제3정규화다. 제3정규화는 일반속성 간에 종속 관계를 떼어내면 된다.


[그림 8] 제3정규화 위배 사례
[그림 8]을 보면, 모델과 표에서 배송업체명이 식별자인 고객번호나 주문일시에 종속되지 않고 일반속성인 배송업체코드에 종속돼 있다. 이 경우가 제3정규화를 위배한 사례로서 일반속성 간에 종속관계가 발생한 이행함수종속이다.

이때는 배송업체명을 고객주문내역에서 삭제하고, 배송업체코드를 식별자로 한 배송업체 엔터티를 만들어 고객주문내역과 릴레이션함으로써 해결할 수 있다.


[그림 9] 그림 8을 제3정규화한 모델
새로운 배송업체 엔터티는 고객주문내역 엔터티와 1:M 관계로 생성된다.

1·2·3정규화 이외에도 Boyce-Codd(엔터티 내에 여러 개의 후보 식별자는 존재하지 않아야 한다), 제4정규화(하나의 엔터티 내에 복수 개의 독립적인 다가속성이 존재할 수 없다) 등이 있다.

당연히 1·2·3정규화 이외의 정규화에 대해서도 알고 모델에 적용할 수 있어야 한다. 하지만 이 책에서는 언급하지 않으니, 모델링에 조금 더 익숙해 지면 꼭 따로 공부하기를 바란다.

이상으로 모델링의 기초 연재를 마친다. ‘시작이 반’이라는 말을 실감하는 기회가 됐으면 한다. 모델링에 대한 감을 제대로 잡고 꼭 심화학습에 도전하기를 기원한다. (끝)

?

출처 : 한국데이터산업진흥원

제공 : 데이터 전문가 지식포털 데이터온에어(dataonair.or.kr)