본문 바로가기

회고/TIL

Database - 정규화

🔥 정규화는 왜 진행해야될까?

정규화를 통해 보다 일관성 있고 정확한 데이터들을 효율적으로 관리할 수 있게 된다. 아래 설명할 제 1, 2, 3 정규화를 통해, 혹은 역정규화를 통해 상황에 맞게끔 데이터들을 관리할 수 있게 된다.

 

  • 제 1 정규화

아래와 같이 만들어진 Students 라는 테이블이 있다 가정을 해보자.

ID 이름 과목명
1 김 철수 JavaScript, TypeScript
2 정 미남 Java, C++
3 백 미녀 Python

 

어차피 이름이 같기때문에 그안에 속한 과목명끼리는 한꺼번에 묶어도 좋을것 같다.

그럼 과목명 이란 속성에 여러가지 데이터가 한꺼번에 들어가도 괜찮을까?

 

💩 No

 

제 1 정규화는 하나의 속성(Column)당 하나의 데이터만을 가지는 것을 의미한다. 그래서 아래와 같이 표현이 되어야 맞을것이다.

ID 이름 과목명
1 김 철수 JavaScript
1 김 철수 TypeScript
2 정 미남 Java
3 정 미남 C++
3 백 미녀 Python

 

 

  • 제 2 정규화

제 2 정규화의 특징은 모든 속성(Column)이 키에 완전히 종속되어 있어야 한다.

아래 표를 확인해보자.

ID 과목명 이름 성적 교수님 강의실
1 JavaScript 김 철수 3.8 David 101호
1 TypeScript 김 철수 4.2 Kevin 103호
2 Java 정 미남 3.6 Bob 202호
3 C++ 정 미남 3.2 Anna 204호
3 Python 백 미녀 4.1 Smith 305호

 

위 테이블은 'ID' 와 '과목명' 이란 복합키로 구성된 테이블 이다.

'성적' 과 '이름' 이란 속성은 두 복합키에 종속되어있는데, 그말인 즉 두 복합키로 인해 도출될 수 있는 값이란 소리이다.

 

하지만 나머지 두 속성 '교수님' 과 '강의실' 을 봐보자.

이 두가지 속성은 과목명만 있어도 충분히 존재할 수 있는 것들이다. 그래서 두가지 테이블로 분리를 해줄 수 있다.

 

 

 

 

첫번째.

두 복합키에 종속되어있는

학생의 이름과 성적이 담긴 테이블

 

 

 

 

 

 

두번째.

'과목명' 단일키 만으로도 분별이 가능한

교수님 성함과 강의실 번호가 담긴 테이블

 

 

  • 제 3 정규화

위 성적 테이블을 통해서 아래와 같은 테이블이 파생되었다고 가정해보자.

ID 평균 성적 장학금 대상여부
1 4.0 T
2 3.6 F
3 3.65 F

 

ID 값을 통해 해당 학생의 평균 성적을 알 수 있고, 4.0 이상인 학생들에겐 장학금이 주어진 다는 사실이 있기에 장학금 대상 여부에 속하는지 아닌지에 대한 부분을 확인할 수 있다.

 

이것을 '이행 종속성' 이라고 하는데 한 테이블 내에 이행종속성이 존재 하느냐 아니냐를 통해 구분지을 수 있다. 이행 종속성을 끊어줌으로서 3차 정규화를 마무리 지을 수 있다.

 

  • 역정규화

'역정규화는 왜 필요할까?' 를 먼저 고민해봐야 할 것 같다. 위와 같은 과정을 거치며 테이블을 쪼개고, 쪼개고를 진행해왔다.

나는 모든 데이터를 한꺼번에 몰아보기 위해서는 JOIN 에 JOIN 을 거듭해야만 한눈에 데이터를 확인할 수 있게 되었다. 이게 단순 1건의 요청 처리라면 문제가 되지 않지만 실제 서버에서는 동시 접속자가 요청 날리는 횟수를 고려해봐야 하기 때문에 최대한 서버에 무리가 가지 않게끔 하는게 중요하다. 과연 테이블을 쪼개는것이 효율적인가? 에 대해 고민을 해보아야 한다는 소리다.

 

대략 50건 정도의 데이터를 가진 테이블이 있는데 이정도는 충분히 서버에서 처리함에 무리가 가지 않는 테이블임에도 불구하고 2개의 테이블로 쪼개서 JOIN 처리를 통해 조회해야만 가져올수있게끔 하면 오히려 불필요한 Cost가 발생하게 된다. 오히려 해당 테이블이 참조하고 있는 테이블과 병합했을 경우에도 데이터 처리에 전혀 문제가 없을 경우를 고려해 합치는것을 역정규화 라고 한다.

 

하나의 테이블이 너무 데이터량이 많아져서 분리를 하는 경우가 존재할 수 도 있고, 혹은 정규화를 통해 성능을 높여야 할때도 있지만 반대로 굳이 GET 요청이 많이 일어나지 않는 테이블이라던지, 혹은 성능적으로 고려 했을때 부모 테이블과 자식 테이블이 병합을 진행해도 무리가 없다 라고 할경우 역정규화도 고려해봐야 한다 라는점을 늘 인지하고 있어야 할것같다.

'회고 > TIL' 카테고리의 다른 글

홈서버 구축기 -1  (2) 2023.09.18
webRTC - socket io  (0) 2023.09.06
DAU & WAU & MAU  (0) 2023.08.29
Postgres - Datatype  (0) 2023.08.21
Redis - cache  (0) 2023.08.19