DB 설계하는 법 (feat. 데이터 모델링)
Programming

DB 설계하는 법 (feat. 데이터 모델링)

부제: 현업에서 DB 설계는 어떻게 진행할까?

 

서론

신입으로 처음 회사에 들어온 뒤 3주만에 DB 테이블을 한번 설계해보라는 업무를 맡았다. 우테코에서 토이프로젝트를 할 때도 테이블 설계를 빡세게 하지 않았던 터라 막막하기만 했다. 부랴부랴 실제 현업에서 사용하는 ERD를 검색해보지만 결과는 거의 나오지 않았다. 그야 당연한 것이 DB 테이블 구조는 회사 기밀이기에 기술블로그에 공개하지 않기 때문이다.

 

우선 급한대로 타사(네이버, 쿠팡)에 들어가 개발자도구를 열어 Response로 어떤 값들이 날라오는지 확인했다. 이를 토대로 필요한 값들을 담은 엔터티를 설계했다. 기획안을 보며 빠진 데이터는 엔터티에 컬럼을 추가해 보완했다.

 

결과물을 사수분께 설명하면서 난 그순간 크게 잘못됐음을 직감했다. 1)엔터티에 대한 근거가 부족했고2)변화하는 요구사항에 대처할 수 없는 모델이었기 때문이다. 그래서 아래 과정으로 테이블을 다시 설계하기 시작했다.

 

DB 테이블 설계 과정

DB 테이블을 설계하는 방법에는 크게 두 가지가 있다. 하향식 방법과 상향식 방법이다.

 

하향식 방법은 타사의 서비스를 참고해 벤치마킹하는 것이다. 위에서 내가 한 방식이 바로 하향식 방법이다. 내가 무의식적으로 하향식 방법을 택했던 이유는 빨리 결과물을 내고 싶었고, 실패하고 싶지 않아서였다. 하향식 방법은 빠르게 엔터티를 도출해낼 수 있고, 설계가 크게 틀리지 않을 수 있다는 장점이 있다. 그러나 이렇게 도출한 엔터티에는 근거가 부족하다. 또한, 수정이 발생할 경우 유연하게 대처가 불가능할 수 있다.

 

상향식 방법은 기획안에 나온 요구사항을 분석해 실체 엔터티를 먼저 도출하는 방식이다. 무에서 유를 창조해내는 방식이기에 시간이 비교적 오래 걸린다는 단점이 있으나, 근거가 명확하고 변경에 용이한 엔터티 설계가 나온다는 장점이 존재한다.

 

여기서는 상향식 방법으로 엔터티를 설계하는 과정에 대해 짚어보고자 한다.

 

상향식 방법으로 엔터티를 설계해보자

상향식 방법으로 엔터티를 설계하는 과정은 다음과 같다.

  1. 기획안을 보며 모든 키워드를 뽑아낸다.
  2. 뽑아낸 키워드를 행위데이터로 나눈다.
    1. 행위와 데이터는 각각 행위 엔터티, 실체 엔터티로 매핑된다.
    2. 다만 모든 행위나 데이터가 DB에 담겨야하는 것은 아니다. 서버에서 ENUM으로 관리하는 데이터도 있을 수 있다.
  3. 2-1에서 설계한 엔터티에 관계를 매핑한다. 명심할 것은 관계는 속성이라는 점이다. 속성이 필요한 이유는 엔터티 간의 조인(join)을 하기 위해서이다.

 

맥도날드 키오스크 테이블을 설계해보자

맥도날드 키오스크 프로그램을 만든다고 가정해보자. 단순히 예시가 아니라 외주를 받아 돈을 받고 프로그램을 만든다고 생각해보자. 기획자가 말하는 모든 요구사항을 구현하기 위해서는 DB에 적절히 데이터가 담길 수 있어야 한다. 편의를 위해 주문, 결제 부분은 제외했다.

 

악명높은 맥도날드 키오스크

 

먼저 기획서에 적힌 요구사항을 살펴보자.

  • 메뉴를 생성/조회/수정/삭제할 수 있어야 한다.
    • 메뉴는 하나 이상의 메뉴그룹과 매핑될 수 있다.
    • 메뉴마다 가격과 칼로리가 존재한다.
    • 메뉴마다 재료를 추가하거나 변경할 수 있다.
    • 메뉴는 판매가능한 시간(모닝, 런치)이 존재한다.
  • 세트메뉴를 생성/조회/수정/삭제할 수 있어야 한다.
    • 세트메뉴는 기본적으로 햄버거 + 감자튀김 + 음료의 조합이다. 대신, 콤보(햄버거 + 음료)처럼 다양한 조합이 나올 수 있다.
    • 햄버거를 제외한 나머지 메뉴는 각 그룹 내에서 교환할 수 있다.

 

1. 기획안을 보며 모든 키워드를 뽑아낸다.

키워드를 모두 뽑아내보면 다음과 같다.

  • 메뉴
    • 가격
    • 칼로리
    • 재료
      • 재료추가
      • 재료변경
    • 판매가능시간
      • 모닝, 런치
  • 메뉴그룹
  • 세트메뉴
    • 햄버거, 감자튀김, 음료
    • 콤보
    • 교환

 

2. 뽑아낸 키워드를 행위와 데이터로 나눈다. 각각은 행위엔터티와 실체엔터티에 매핑된다.

위에 뽑아낸 키워드를 통해 내가 먼저 설계한 실체엔터티는 다음과 같다.

실체 엔터티란

실체 엔터티란 말그대로 실제로 보이는 것을 나타내는 데이터를 관리하는 엔터티를 말한다. 쉽게 말해 만질 수 있는 데이터이면 실체 엔터티이다. 여기선 메뉴, 재료, 세트가 실체 엔터티이다. 메뉴그룹은 실제로 만질 수 없으나 실체 엔터티에 준한다고 생각해 실체 엔터티로 분류했다.

실체 엔터티가 중요한 이유

실체 엔터티는 모델 구조적으로 최상위에 존재하기 때문에 중요하다. 실체 엔터티는 모델의 뼈대를 담당하기 때문에, 실체 엔터티 설계를 잘하면 모델의 근간이 튼튼해진다. 데이터 모델링 과정에서 실체 엔터티를 설계하는 데 가장 많은 시간을 투자해야 한다.

 

 

요구사항을 분석하다보면 다대다관계가 존재한다. 위의 요구사항에서는 아래와 같은 다대다 관계를 생각해볼 수 있다.

  • 하나의 세트는 여러 메뉴를 가질 수 있다. 메뉴 역시 여러 세트에 속할 수 있다.
  • 하나의 메뉴는 여러 재료를 가질 수 있다. 재료 역시 여러 메뉴에 속할 수 있다.

테이블을 설계할 때 다대다 관계라는 개념이 정말 어려웠다. 그러나 실체 엔터티라는 뼈대만 잘 설계한다면 다대다 관계는 어렵지 않다. 그저 테이블을 하나 더 만들면 되는 것이다.

 

위 요구사항에서 세트메뉴, 메뉴재료라는 다대다 테이블이 생겨났다.

 

3. 관계를 매핑한다.

이제 엔터티 간의 관계를 매핑할 차례이다. 관계는 그저 엔터티 내 속성일 뿐이다. 그래서 관계선이 없어도 다른 엔터티 내 속성을 갖고 있다면 관계가 형성된다.

 

아래 빨간색으로 표시한 속성이 바로 그 속성이다.

 

식별관계와 비식별관계

관계를 매핑할 때 알아두어야 할 개념이 있다. 바로 식별관계와 비식별관계이다.

 

식별관계는 부모 테이블의 기본키를 자식 테이블의 기본키(=PK)로 설정하는 방식이다. 이와 반대로, 비식별관계는 부모 테이블의 기본키를 자식 테이블의 외래키(=FK)로 설정하는 방식이다. 위에서 세트메뉴, 메뉴재료는 식별관계로 설정했고 세트, 메뉴는 비식별관계로 설정했다.

 

현업에서는 보통 식별관계보다 비식별관계를 선호한다. 그 이유는 구조 변경에 용이하기 때문이다. 즉, 식별관계는 자식 엔터티가 늘어날 수록 주키가 계속해서 쌓이기 때문에 구조를 쉽게 변경할 수 없다.

 

마지막으로 관계선을 만들면 완성이다.

 

결론

데이터 모델링을 어떻게 공부해야할 지 막막했다. 그때 내게 큰 도움이 된 책은 『김기창의 데이터 모델링 강의』 (위즈덤마인드, 2022) 였다. 실체엔터티와 행위엔터티라는 개념, 그리고 ‘관계는 속성이다’라는 것까지 모두 이 책을 통해 배웠다. 이 책의 저자는 데이터 아키텍처 분야에서 20년 이상 일한 전문가이다. 데이터 모델링이라는 어려운 개념을 쉽게 설명해주어서 참 고맙다.

 

처음부터 완벽한 테이블을 설계할 수는 없다. 그러나 실체 엔터티라는 뼈대를 잘 설정한다면 나중에 요구사항이 추가되더라도, 변경에 용이한 테이블은 충분히 설계할 수 있다고 생각한다.