[DB] 데이터 정규화

hoifoi·2024년 1월 7일
post-thumbnail

들어가면서

이전엔 컨텐츠를 다루는 일을 하다가
백엔드 개발자에 대한 첫 관심이 생기게 된 계기가 바로 데이터를 다루면서였다
당시에는 정말 별거 아닌 몇 개의 SQL쿼리를 슥삭슥삭 하면서 정말 재밌넹!
하면서 하고 싶다는 생각이 얕게나마 들었었는데 실제로 해보니 너무 재밌었다..!!
API를 다루는 코딩의 영역도 좋지만 어떤 데이터를 어떻게 담느냐 고민하는 게
나한테는 더 즐거운 영역이었던 것 같다
(정말 다행히 이부분을 즐거워해서 프로젝트를 안전하게 끝낼 수 있었던 것 같다..)

항상 프로젝트 시작은 프/백 구별없이 기획부터 시작했지만
처음으로 각 영역별로 회의 하는 것은 처음엔 데이터베이스 설계였는데
정말 가르쳐준 것만 알고 들어가다보니(심지어 가르쳐준것도 잘은 모른채로 였지만)
엄청난 설계 수정을 겪었었다..
매번 프로젝트때마다 적게는 10번에서
많게는 20번 정도 데이터베이스 구조를 엎었는데

일정 API가 만들어진 중기단계에서 데이터베이스를 엎는 날엔..
정말 눈물이 앞을 가리기도 했었고 바꾸지 않으려(?) 애도 써봤지만
바꿔야 한다는 짧은 생각이 드는 순간부터는 어떻게 덜 바꾸냐를 고민하지
안바꿀 수는 없었다..

그때도 그렇고 지금도 그렇지만
조금이라도 더 알았다면 그렇게까지 바꿀 필요는 없지 않았을까 하면서..
테이블 설계에서 필요한 지식인 데이터 정규화에 대해서 포스팅 해보겠다!

데이터정규화란?

사칙연산이란 무엇이죠?
더하고 빼고 곱하고 나누는 것입니다!
와 같이 말만 번지르르 할 뿐 아주 쉬운 개념이다!
(하지만 모르면 꽤나 고생하는 부분이기도 한..)

간단하게 말하면
데이터의 중복과 일관성을 유지하기 위한 효율화! 라고 생각하면 되겠다
관계형 데이터베이스는 특히나 이 부분을 아주 잘 이해하고 다룰 줄 알아야 한다!
(이해하기 싫으면 NoSQL를 쓰라고도 하지만 역시나 그부분도 관계형인 함정..)

자 그럼 조금 더 자세히 알아보자!

제 1정규화

데이터는 한칸에 하나씩!

아주 심플하게 복수의 데이터를 같은 칸에 넣지 말자는 말이다!
아직 조금 와닿지 않는다면 바로 예시를 들어보겠다!

NAMECOURSE
이하늘캘리그라피, 통기타, 십자수
이수진통기타, 십자수
강민주우쿨렐레

이렇게 한명이 2마리 이상의 애완동물을 데리고 있다면
우리가 수기로 작성했던 저 방식이 편해보일 순 있지만
입력된 데이터를 찾거나 수정하거나 입력할 때 불편함이 생긴다
(잘 찾더라도 이후 API에서 데이터 가공이 좀 빡세다..)

그래서 이런 경우에는

NAMECOURSE
이하늘캘리그라피
이하늘통기타
이하늘십자수
이수진통기타
이수진십자수
강민주우쿨렐레

이렇게 입력을 시키는 것이다!

이 때의 장단점을 살펴보면

장점

  • 데이터 핸들링이 쉬워짐(조회, 수정 및 재가공)

단점

  • 데이터 입력이 조금 번거로워짐(같은 이름의 다른 클래스와 같은 경우)
  • 중복 데이터가 조회되는 경우가 생김(완전히 같은 경우는 아니고 일부 칼럼)

제 2정규화

반복되는 자료는 분리!

제 1정규화 이후에 보이는 반복되는 자료를 분리하는 것이다!
(이 때 고유 값이 아닌 것을 분리한다! 라고 생각해주면 된다)

아래 테이블을 취미 클래스 등록 현황 테이블이라고 생각해보자

NAMECOURSEPRICE
이하늘캘리그라피5000
이하늘통기타7000
이하늘십자수3000
이수진통기타7000
이수진십자수3000
강민주우쿨렐레4000

여기서 빼도 되는 데이터를 생각해보자면
NAME은 고유값인 동시에 확실히 알아야 하는 클래스 등록 주체이기 때문에
따로 빼면 그만큼 번거로울 수 있다!

COURSE 같은 경우에도 어떤 클래스를 등록했는지 알아야 하는
확실하게 표시되어야 할 데이터이기 때문에 뺐을 때 번거로워진다

그럼 PRICE는 어떨까?
등록현황을 우선적으로 알아봐야 할 테이블이기 때문에
당장은 빼도 상관이 없고 가격 변동시에
모든 가격 데이터를 수정해야 할 일이 생기기 때문에
따로 빼서 관리하면 그 번거로움도 해소할 수가 있다!

이렇게
그 데이터를 뺐을때 불편한지수정이 얼마나 자주 일어나는지를 따지면
제 2정규화 할 데이터가 무엇일지 확실하게 구별할 수 있다!
개념적으로 따지자면 다른 칼럼에 종속된 칼럼을 분리한다!라고 보면 된다
(가격이라는 값은 어떤 물건에 붙어 있는 태그와 같이 종속되어있는 관계)

이렇게 제 2정규화를 하게 되면?

이렇게 등록 현황테이블과 각 코스 금액테이블로 분리할 수가 있다!

이 때의 장단점을 살펴보면

장점

  • 데이터 핸들링이 쉬워짐(조회, 수정 및 재가공)

단점

  • 데이터 입력이 조금 번거로워짐(같은 이름의 다른 클래스와 같은 경우)
  • 모든 칼럼 조회시 분리된 테이블을 참조해야하는 번거로움이 생김

제 3정규화

한번 더 반복되는 자료를 분리!

제 2정규화 이후 다시 한번 더 반복되는 자료를 분리하는 것이다!

바로 예시를 들어보면 제2정규화된 테이블에 다시 다른 칼럼(상세 정보)가 추가되었다!

COURSEPRICEMENTOR
캘리그라피5000LEO
통기타A7000STEVE
통기타B8000ROKI
십자수3000ETHAN
우쿨렐레4000SUNNY

이제 제 2정규화 할 때와 같은 방식으로 생각해보면!
클래스 정보 테이블에서는
뭘 배워야 할지 알아야 하기 때문에 COURSE는 빠지면 안된다!
얼마인지 가격이 중요하기 때문에 PRICE는 빠지면 안된다!
누가 가르치느냐에 따른 질이 다르기 때문에 MENTOR도 빠지면 안된다!
근데 소속 팀까지 중요한가?

이렇게 빠져서 될지 안될지 그리고 다른 칼럼에 종속되어있는지를 살피는 것이다
이렇게 제 3정규화까지 해보면!

하지만 이 부분에서도 장단점이 있다!

장점

  • 데이터 핸들링이 쉬워짐(조회, 수정 및 재가공)

단점

  • 다시 한번 데이터 입력이 조금 번거로워짐(같은 칼럼의 다른 종속 칼럼 데이터)
  • 모든 칼럼 조회시 분리된 테이블을 한번 더 참조해야하는 번거로움이 생김

그러면 어떻게 하라고?

위에서 본 내용과 같이 테이블이 분리 될수록
모든 데이터를 한꺼번에 보려면 독립된 테이블을
한번씩 더 참조해야하는 번거로움이 생겼지만
그럴수록 데이터 핸들링이 더 쉬워지게 되었다!

하지만
제 3정규화 부터는 굳이 해야하나? 싶은 생각이 스멀스멀 들것 이다
하지만 결과적으로는 결국 제 3정규화까지 하게 될 것 이다!
기본적인 서비스 안에서는 데이터의 칼럼이 6개 이상이 쌓일 것이기 때문

클론하기 좋다던 인스타그램이나 쓰레드를 클론 할 때도
정규화는 결국 끝까지 해야 할 수 밖에 없었다
특정 유저 - 그 유저의 포스트 - 댓글 - 대댓글 - 좋아요 - ...

이렇기 때문에 마음껏 정규화를 할 수 있는 여건은 항상 넘치는데
그 종속성과 고유 값을 확실히 구별해서 정규화를 하는 것이 중요하다
(이 부분에서 잘못되면 나중에 결국 설계를 몇번이고 엎게 된다..)

마무리

별 것 아닌 것 같으면서도 꼭 알아야 할 부분에 대해서
최대한 쉽고 간단하게 설명해보았는데 그리 쉬워보이진 않는다..ㅜ
하지만 이렇게 개념적인 부분을 한번 알고 나서
앞으로 보이는 모든 서비스의 데이터는 어떻게 저장되고 있을지 곱씹어보면
금방 이해가 될 것이다!(그리고 이제는 폰을 들어도 놀지 못하게 된다..)

힘들지만 배우는 과정이다보니 항상 성장해가는 느낌이라
그래도 즐겁게 배우는 것 같다! 여러분도 그렇게 성장해가길..
(은 무슨.. 이라 생각들더라도 결국 해야 할 일이니 미리 하는 게 좋을 것이다..ㅎ)

++
발돋움 중인 예비 개발자 입니다.
태클 및 의견 공유 언제나 환영 :D

profile
컨텐츠 기획자 출신 백엔드 개발자 :D

0개의 댓글