데이터베이스

[데이터베이스] 데이터 정규화

취업 드가자잇 2024. 6. 13. 16:27

 

 

데이터 정규화란 DB 설계에서 중복을 최소화하고 일관성을 유지하기 위한 과정을 의미한다.

데이터 정규화를 통해 데이터 중복이나 종속 관계의 불일치로 인해 발생하는 이상 현상을 방지할 수 있다.

데이터 정규화에는 크게 3가지 단계가 있는데, 제 1정규화, 제 2정규화, 그리고 제 3정규화가 있다.

 

제 1 정규화

정규화에 대한 설명을 찾아보았지만 빡통이라 직관적으로 이해하는 것이 힘들었다. 

필자가 제 1정규화에 대해 이해한 핵심은 하나의 컬럼에는 하나의 데이터만 담는 것이다.

이에 대한 좋은 예시로 필자가 자주 보는 코딩애플형님의 영상이 있으니 시간나면 한번 씩 봐보길 권한다. 

출처: 유튜브 코딩애플 (https://www.youtube.com/watch?v=Y1FbowQRcmI)

 

그렇다면 제1정규화를 왜 해야하는 걸까? 

위에 예시를 기준으로 설명하면 나중에 DB에서 데이터를 찾고 싶을때, '골프 초급'을 신청한 사람의 데이터를 가져올때 쿼리문이 좀 더 길어지고 귀찮아질 수 있다는 것이다. 물론, 이로 인해 성능 저하 이슈도 있을 수 있다.

 

제 2 정규화

제 2정규화의 사전적인 의미는 partial dependency(부분 종속)를 제거한 테이블이다. 

쉽게 말하자면, 현재 테이블의 주제와 관련성이 떨어지는 컬럼을 다른 테이블로 빼는 작업을 의미한다고도 볼 수 있다. 

출처: 유튜브 코딩애플 (https://www.youtube.com/watch?v=Y1FbowQRcmI)

 

이를 설명하기 위해 Compositie primary key(복합 primary key)라는 개념이 있다.

우선, primary key는 알다시피 테이블내에서 각 행을 고유하게 식별하기 위한 값이다. 

위 예시를 살펴보면 회원번호 103이 중복되는 것을 볼 수 있고, '김민수' 회원의 이름또한 중복되어 primary key로서의 역할을 할 수 없다는 것을 확인할 수 있다.

하지만 회원번호와 프로그램을 조합하면 primary key처럼 설정하여 각 행을 고유하게 식별할 수 있다.

이를 Composite primary key라고 부른다. 

 

그리고 이러한 Composite primary key중 하나의 컬럼 혹은 부분적으로 종속되는 컬럼을 partial dependency를 가진다고 한다.

즉, 제 2정규화는 이러한 컬럼을 따로 분리하는 것을 의미한다.

예를 들어, 위 예시의 테이블이 회원들의 등록 현황이라고 한다면, 프로그램의 가격을 나타내는 컬럼은 해당 주제와 다소 관련성이 떨어져보인다는 것을 확인할 수 있다. 

 

제 3 정규화 

뭔가 할만큼 한거같지만 아직 제 3 정규화가 남았다...

제 2 정규화가 복합 primary key에 부분적으로 종속된 컬럼들을 분리하는 작업이었다면, 제 3정규화는 거기서 발전해 일반 컬럼에 종속된 테이블의 큰 주제와 관련성이 적은 일반 컬럼에만 종속된 컬럼을 분리하는 것을 의미한다. 

다른 멋있는 말로는 모든 컬럼이 기본 키에 대해 이행적 함수 종속성을 갖지 않도록 설계한다는 것이다.

ex) A → B, B → C와 같은 꼴의 함수 종속 관계에서 A → C와 같은 이행적인 함수 종속 관계가 성립하는 것을 말한다

출처: 유튜브 코딩애플 (https://www.youtube.com/watch?v=Y1FbowQRcmI)
출처: 유튜브 코딩애플 (https://www.youtube.com/watch?v=Y1FbowQRcmI)

 

위 사진은 제 3정규화를 통해 강사들의 출신 대학을 다른 테이블로 분리한 제 3정규형을 만족하는 하나의 예시이다. 

이러한 귀찮은 과정을 굳이 행하는 이유는 당연히 그만한 장점이 있기 때문일 것이다.

장점은 데이터의 수정이 편리해진다는 것이다. 

예를 들어, 제 3정규화를 거치기 이전에는 '이상구' 강사의 출신 대학값이 변경되거나 했을때 이를 두번 수정해줘야했는데 테이블을 따로 분리함으로서 수정작업을 한번만 거쳐도 되게 되었다는 것을 확인할 수 있다.

추가로, 데이터의 중복이 줄어들어 데이터 일관성과 무결성이 유지된다는 것은 정규화의 전반적인 장점이다. 

 

정규화는 언제나 옳은가?

여기까지 들으면 정규화는 무조건 좋은 것처럼 보인다.

하지만 이전에 현업에 계신분에게 이에 관해 질문했을때는 제 1 정규화도 안하는 경우가 많다는 이야기를 들었다.

왜냐하면 정규화를 수행하면 데이터의 중복이 줄어들어 데이터 일관성과 무결성이 유지되지만 이로 인해 조회 성능이 저하될 수 있기 때문.

 

반 정규화

회원 테이블 (Members)

회원번호                                                                           회원이름

101 강호동
102 손흥민
103 김민수

 

프로그램 테이블 (Programs)

회원번호                               프로그램                                                                     가격                                                납부여부

101 스쿼시초급 5000 0
102 헬스 6000 1
103 헬스 6000 1
103 골프초급 8000 0

 

위 예시와 같은 테이블이 있다고 가정했을때, 회원이름과 프로그램 정보를 조회하려면 두 테이블을 조인해야 한다. 

여기서 조인(Join)이란 두 개 이상의 테이블을 결합하여 원하는 데이터를 추출하는 SQL 연산을 의미한다. 

회원이름과 프로그램 정보를 조회할려면 다음과 같은 쿼리문을 작성해야할 것이다.

SELECT Members.회원번호, Members.회원이름, Programs.프로그램, Programs.가격, Programs.납부여부
FROM Members
JOIN Programs ON Members.회원번호 = Programs.회원번호;

 

보다시피 단순히 데이터를 조회하는 행위치고는 쿼리문이 다소 복잡하다는 것을 확인할 수 있다. 

그렇기에 조회성능이 중요한 경우 반정규화를 통해 중복된 데이터를 허용함으로서 성능을 향상시킬수도 있는 것이다. 

물론 복잡한 조인을 사용하는 것보다 쿼리문이 줄어들어 데이터를 사용하는 것이 더 쉬울 수도 있다는 장점도 있다. 

 

반 정규화를 하는 방법

회원-프로그램 테이블 (MembersPrograms)

회원번호                      회원이름                             프로그램                                                    가격                                    납부여부

101 강호동 스쿼시초급 5000 0
102 손흥민 헬스 6000 1
103 김민수 헬스 6000 1
103 김민수 골프초급 8000 0

 

1. 중복 데이터 허용: 정규화된 테이블을 여러 개 생성하는 대신 중복된 데이터를 포함하는 하나의 테이블을 만든다.

2. 테이블 병합:  빈번하게 조인되는 테이블은 하나의 테이블로 합치는 것이 성능상 유리할 수 있다

SELECT 회원번호, 회원이름, 프로그램, 가격, 납부여부
FROM MembersPrograms;

 

보다시피 쿼리문의 길이가 많이 줄어들었고, 직관적으로 어떠한 의미인지 이해하기 쉬워졌다.

공부를 하다보며 느끼는 것이지만 결국 특정 기술이나 방법론이 항상 옳다는 것은 없는 것 같다. 

언제나 상황과 맥락에 따라 기술이나 방법론을 적절히 선택하고 적용하는 것이 좋은 개발자의 자세라는 것을 오늘도 체감한다.