SQL 캠프 광고 이미지
  • SQL

알아두면 쓸데있는 데이터 모델링 (1) 정규화

SQL 캠프 광고 이미지
SQL 캠프 광고 이미지
⚠️ 이 시리즈는 관계형 데이터 모델링에 입문하시는 분들을 위해 쓰였습니다. 용어 사용을 아주 엄밀하게 하기보다는, 쉽고 직관적으로 이해할 수 있도록 쓰는 데 집중했어요. 데이터 모델링이 처음인 분에게 추천합니다.
 
🔖
알아두면 쓸데있는 데이터 모델링 모아보기
  1. 정규화
  1. 여러 종류의 Key 이해하기 (feat. PK, FK는 무엇인가?)
  1. ER 모델의 구성 요소 - 엔티티, 속성, 관계 [✨ 로그인 전용]
  1. ERD 읽어보기 [✨ 로그인 전용]
  1. 엔티티 톺아보기 [✨ 로그인 전용]
  1. 속성 톺아보기 [✨ 로그인 전용]
 
이 글은 나른한 오후에 쓰고 있습니다. 잠을 좀 쫓아보려고 커피를 한 잔 사 왔어요. 아래는 커피 결제 영수증입니다.
 
notion image
 
이 영수증 데이터가 데이터베이스에서 어떻게 관리되고 있을지 갑자기 궁금해졌어요 🤔 (하나도 궁금하지 않다고요? 데이터를 사랑하는 여러분이 그럴 리가요!) 그래서 <영수증>이라는 테이블을 만들어 보았습니다.
 
Table <영수증>
상호명
사업자 번호
전화 번호
주소
메뉴 1
메뉴 2
카드 번호
승인일시
카페 데이터리안
116-**-*****
010-5***-****
서울시 광진구 뚝섬로
아이스 아메리카노
레몬 쌀 파이
****-****-****-****
202*-10-13 12:41:21
 
이렇게 하나의 테이블로 모든 데이터를 관리한다면, 어떤 문제점이 생길 수 있을까요?
 
  • 만약 매장의 주소가 바뀌면 모든 데이터의 주소 데이터를 업데이트해야 합니다. 매장 이름이나, 전화번호도 마찬가지입니다. 또한 매장의 주소 같은 정보가 중복으로 저장되어 저장 공간도 많이 차지합니다.
  • 주문이 한 번도 발생하지 않은 메뉴 데이터를 관리할 수 없습니다. 같은 원리로 레몬 쌀 파이 데이터를 삭제하면 레몬 쌀 파이라는 메뉴도 함께 삭제됩니다.
  • 한 번 주문할 때 메뉴는 최대 2개까지만 가능합니다.
 
이렇게 설계가 잘못된 테이블에 데이터를 담았을 때 여러 가지 문제들이 생길 수 있습니다. 사실 이런 문제는 데이터 간의 종속 관계에 따라 테이블을 잘 정리해 주면 대부분 해결할 수 있습니다. 이걸 어떻게 하는 것이 최적인가에 대한 방법론이 바로 정규화 이론입니다. 아직은 ‘종속’, ‘테이블의 관계’라는 말이 어색할 텐데요. 정규화 이론에 관해서 얘기하면서 차근차근 풀어나가 보겠습니다.
정규화 이론이라고 하니 좀 어렵고 딱딱해 보이지만, 상식 선상에서 모두 이해할 수 있습니다. 혹시 글을 보다가 막히는 부분이 있으면 당황하지 말고 ‘상식적으로 다시 생각해 보자 💭’는 마음가짐으로 내용을 곱씹어 보시면 좋겠어요. 저한테는 이런 마음가짐이 모델링 공부를 놓지 않는 데 도움이 많이 됐습니다.
 
 

제1정규화

아래와 같이 카페의 정보를 관리하는 테이블이 있다고 생각해 봅시다. 메뉴라는 컬럼에 값이 여러 개가 들어가 있습니다. 한 카페에서 여러 메뉴를 팔 수 있기 때문입니다. 제1정규화 원칙은 이런 상황에서 하나의 값만 가져야 한다는 것입니다.
 
Table <카페>
카페 ID
상호명
연락처
메뉴
1
로우키
070-8824-2010
에스프레소, 아메리카노, 카페 라떼, 바닐라 라떼
 
테이블 모양이 약간 다르지만, 아래의 경우도 마찬가지입니다.
 
Table <카페>
카페 ID
상호명
연락처
메뉴 1
메뉴 2
메뉴 3
메뉴 4
1
로우키
070-8824-2010
에스프레소
아메리카노
카페 라떼
바닐라 라떼
 
이렇게 하나의 셀에 여러 개의 값이 들어간 경우 또는 개념적으로 중복되는 컬럼이 있는 경우에는 아래와 같이 별도의 테이블로 분리해야 합니다.
 
Table <메뉴>
카페 ID
메뉴
1
에스프레소
1
아메리카노
1
카페 라떼
1
바닐라 라떼
 
이게 제1정규화입니다! 어렵지 않죠?
카페 정보를 관리하는 것보다 좀 더 일반적인 예시는 주문 테이블일 거예요. 일반적으로 하나의 주문에 여러 종류의 상품이 속할 수 있으므로 주문과 주문한 상품은 각각 <주문>, <주문 상세> 테이블로 분리하여 관리합니다. 아래와 같은 식으로요.
 
Table <주문>
주문 번호
주문 날짜
회원 번호
536365
2018-12-01
17850
 
Table <주문 상세>
주문 번호
상품 코드
주문 수량
536365
22715
12
536365
51914A
12
 
 

제2정규화

제2정규화에 관해 얘기하기 전에, 한 가지 용어를 정리하고 넘어가겠습니다. 아마 이 글을 보시는 분들은 아래 테이블에 있는 카페 ID, 상호, 연락처를 컬럼(Column)이라고 부르는 데 익숙할 겁니다.
 
Table <카페>
카페 ID
상호명
연락처
1
로우키
070-8824-2010
 
데이터 모델링 세계에서는 이것들을 데이터의 ‘속성(Attribute)’이라고 부릅니다. 데이터를 설명하는 요소라는 뜻이지요. 2차원의 테이블에 이 속성을 컬럼으로 표시하기 때문에 ‘컬럼’, ‘속성’, ‘어트리뷰트’라는 단어가 혼재되어 사용되는데요. 저는 이 글에서 앞으로 ‘속성’이라고 부르겠습니다.
 
이번에는 아래와 같은 테이블이 있다고 생각해 보겠습니다. 어떤 상품을 주문했는지 정보를 저장하는 주문 상세 테이블입니다.
 
Table <주문 상세>
주문 번호
상품 코드
상품명
상품 가격
주문 수량
536365
22715
Card Wedding Day
10.68
12
536365
51914A
Feather Pen Hot Pink
11.12
12
536366
22633
Hand Warmer Union Jack
12.15
6
 
각 데이터를 고유하게 식별할 수 있는 최소한의 속성을 후보 키(Candidate Key)라고 부르는데요. 이 테이블에서 후보 키는 주문 번호와 상품 코드의 조합입니다. 보통은 행을 대표하는 하나의 속성이 후보 키가 되는 경우(예. <주문> 테이블의 주문 번호)가 많은데, 종종 이렇게 두 속성의 조합이 후보 키가 되는 경우도 있습니다.
 
Table <주문 상세>의 속성
  • 주문 번호 (후보 키)
  • 상품 코드 (후보 키)
  • 상품명
  • 상품 가격
  • 주문 수량
 
제2정규화는 후보 키가 아닌 속성(상품명, 상품 가격, 주문 수량)이 후보 키 전체(주문 번호, 상품 코드)에 종속되어야 한다는 겁니다. 말이 어렵죠? 차근차근 뜯어볼게요.
여기에서 ‘종속’은 직관적으로 이해할 수 있는 개념입니다. Y가 X에 종속적이라는 말은 X가 Y를 결정한다는 말과 같은 말입니다. 예를 들어, 상품 코드를 알면 상품명과 상품 가격을 알 수 있죠. 이럴 때, ‘상품명과 상품 가격이 상품 코드에 종속적이다’라고 하고 아래처럼 표현합니다.
 
 
다시 제2정규화 얘기로 돌아와 볼까요? 후보 키가 아닌 속성(상품명, 상품 가격, 주문 수량)이 후보 키 전체(주문 번호, 상품 코드)에 종속되어야 한다고 얘기했었습니다. 다른 말로 하면, 일부 후보 키 속성에만 종속적인 속성이 있으면 제2정규화 원칙에 위배된다는 뜻입니다.
주문 수량의 경우, 주문 번호와 상품 코드가 함께 주문 수량이라는 값을 결정하므로 제2정규화 원칙에 부합합니다. 많은 주문 상세 데이터 중에 어떤 주문에서(주문 번호), 어떤 상품을(상품 코드) 구매한 데이터를 보겠다고 특정하면 몇 개를 샀는지(주문 수량)도 알 수 있게 되니까요. 주문 번호만 알아서는 주문 수량을 특정할 수 없고, 상품 코드만 알아서도 주문 수량을 특정할 수 없습니다.
 
 
하지만 상품명과 상품 가격은 주문 번호라는 속성과는 관련이 없고, 상품 코드라는 속성에만 종속되어 있습니다. 주문에 따라서 상품 이름이나 가격이 달라지지는 않으니까요.
 
 
이는 후보 키가 아닌 속성이 후보 키 전체에 종속되어야 한다는 제2정규화 원칙을 위배합니다. 이렇게 일부 후보 키 속성에만 종속적인 속성(상품명, 상품 가격)은 별도 테이블로 분리해야 합니다. 제2정규화 원칙은 이렇게 후보 키가 2개 이상인 경우에 꼭 생각해 봐야 하는 원칙입니다. ‘혹시 일부 후보 키에만 종속적인 속성이 있나?’ 살펴봐 주세요.
 
Table <주문 상세>
주문 번호
상품 코드
주문 수량
536365
22715
12
536365
51914A
12
536366
22633
6
 
Table <상품>
상품 코드
상품명
상품 가격
22715
Card Wedding Day
10.68
51914A
Feather Pen Hot Pink
11.12
22633
Hand Warmer Union Jack
12.15
 
 

제3정규화

이번에는 아래와 같은 데이터를 가정해 보겠습니다. 온라인 쇼핑몰의 주문 데이터입니다.
 
Table <주문>
주문 번호
주문 날짜
회원 번호
이름
국가
536365
2018-12-01
17850
Tom Holland
United Kingdom
540365
2019-01-06
12413
Adèle Haenel
France
 
지금까지 배운 것을 이용해 <주문> 테이블의 속성들을 적어보겠습니다.
 
Table <주문>의 속성
  • 주문 번호 (후보 키)
  • 주문 날짜
  • 회원 번호
  • 이름
  • 국가
 
테이블에서 후보 키가 아닌 속성들은 모두 후보 키에 종속되어야 합니다. 그런데 겉으로는 그런것으로 보이지만, 실제로는 후보 키가 아닌 다른 일반 속성에 종속된 속성들이 있을 수 있습니다. 이 예에서는 이름, 국가가 그렇습니다. 이름과 국가는 테이블의 후보 키인 주문 번호에 종속된 것이 아니라, 회원 번호라는 일반 속성에 종속되어 있습니다.
 
 
이를 별도의 테이블로 분리하는 것이 제3정규화입니다. 정규화하고 나면 아래와 같이 <회원>이라는 테이블이 새로 생깁니다.
 
Table <주문>
주문 번호
주문 날짜
회원 번호
536365
2018-12-01
17850
540365
2019-01-06
12413
 
Table <회원>
회원 번호
이름
국가
17850
Tom Holland
United Kingdom
12413
Adèle Haenel
France
 
 

마무리

사실 제1~3정규화 원칙 이외에도 몇 가지가 더 있는데요. 실무에서는 여기까지만 알아도 충분합니다.
정규화 이론은 데이터 모델링의 꽃이라고 불릴 만큼 핵심적인 이론입니다. 그런데 상식 선상에서 다 이해가 되는 내용이었죠. 이론을 모르고도 정규화를 잘해서 모델링을 하고 있던 분도 있을 것입니다.
사실, 관계형 데이터 모델은 집합론(Set theory)의 관계형 이론(Relational theory)이라는 수학적인 이론을 바탕으로 합니다. ‘관계형’이라는 이름 자체가 이 수학 이론의 이름에서 왔습니다. 그러다 보니, 수학적으로 설명해 놓은 문서들이 많습니다. 처음 배우는 입장으로는 참 난감하죠. 저 역시 그렇게 느꼈습니다. 하지만 알고 나니 꼭 엄밀한 수학 용어로 설명하지 않아도 정규화의 본질을 이해하는 데에는 문제가 없겠더라고요. 우리가 이 이론을 연구하는 사람들도 아니고, 실무에서 필요한 정도로 이해하고 있으면 되는 거잖아요? 그래서 이 글은 정규화 이론을 쉽게 이해하는 데에 초점을 맞추어 써보았습니다. 혹시 엄밀하지 못한 용어 사용에 마음 한구석이 불편해진 분들이 계신다면 심심한 사과의 말씀을 드립니다. 😅
이번 글에서 ‘후보 키(Candidate Key)’라는 용어를 많이 썼는데요. 무언가의 후보가 된다는 뜻이겠죠? 데이터 모델링 세계에는 후보 키 이외에도 슈퍼 키(Super Key), 기본 키(Primary Key, PK), 대체 키(Alternate Key), 외래 키(Foreign Key, FK) 등 다양한 Key가 있습니다. 여러 가지 종류의 Key를 이해하고 나면 데이터 모델링을 하는 시야가 한층 넓어질 거예요. 이 중에서 PK, FK는 아마 ERD에서도 자주 보셨을 겁니다. 다음 글에서는 다양한 종류의 Key에 관해서 이야기를 해보겠습니다.
 
 

추천 자료

데이터 모델링을 좀 더 깊게 공부해 보고 싶은 분에게는 <핵심 데이터 모델링> 이라는 책을 추천합니다.
2024년에는 ‘SQL 데이터 분석 캠프’ 시리즈의 끝판왕 ‘SQL 데이터 분석 캠프 | 마스터반’ 런칭도 계획하고 있어요. 지금 열심히 강의안을 쓰고 있는데요. 데이터 모델링도 한 꼭지로 다룰 예정이니 기대 많이 해주세요. 👋🏻
 
윤선미데이터 분석가

어느새 7년차 데이터 분석가이고, 4년째 데이터 분석 교육을 하고 있습니다. 데이터리안 멤버들과 함께 일하면서 데이터의 힘을 더 믿게 되었습니다.

함께 읽어보면 좋은 글

주식회사 데이터리안