mongoDB 모델링을 해보자


처음 시작할 무렵의 글들에도 언급을 했지만 내가 지금 가지고 있는 지식이라고는 “몽고 디비 

완벽 가이드”라는 책 한권 읽은 것이 전부이다. 그마저도 변변한 선행 지식이 없이 읽었던 터라 

지금 기억나는 부분은 거의 없다시피 하다.


그나마 다행인 것은 내가 지금 하고자 하는 것이 mongoDB은 전반적인 내용을 알고자 하는 것이 

아니라 응용 프로그램을 위한 데이터 모델을 설계하고자 하는 것이기에 부담이 좀 덜하다는 것 

정도?


물론 읽기와 쓰기의 빈도를 고려하고 한 번에 저장할 수 있는 Document의 최대치라든지 성능을 

위한 정규와화 비정규화의 적절한 선택 등을 생각해보면 그래도 알아야 할 것들이 상당히 많다. 

그래서 조금이라도 그런 부담을 줄이기 위해 최대한 데이터 볼륨을 작게 하려고 한다(물론 

나중에는 점점 확장이 될 것이고 그 확장되는 부분도 고려해야 할 문제이긴 하다).


1. 기능 목표


전체 메뉴에 대해 Spring Rest API를 통해 mongoDB에 데이터의 CRUD 처리를 하는 

        기능을 구현한다. 대상이 되는 기능은 지난 주 작업했던 Sign-up을 제외하고 Login, 

        목표 등록, 목표 수정, 요소 등록, 상세 프로필 등록, 상세 프로필 수정 등이다.


2. 기술 목표


서두에 적었듯이 오늘은 mongoDB의 데이터 모델링을 해볼 예정이다. 이미 알고있는 바와 

        같이 mongoDB는 Document DB로 분류되어 JSON과 거의 동일한 형식으로 데이터가 저장

        되며 스키마가 없는 DB로 데이터 설계에 있어서 비교적 자유롭다는 장점이 있다. 더불어 

        mongoDB는 중첩된 Object를 가진 데이터 설계가 가능하다는 부분도 장점이다. 가능하면 

        이러한 mongoDB의 장점을 활용하는 선에서 단순하게 설계를 해보고자 한다.


3. 기술 적용 내용


본론에 들어가기 전에 먼저 mongoDB의 모델링 가이드에 대해 간단하게 살펴보고 시작

        하도록 하자.


일단 기존 RDBMS와의 용어상 차이를 보면 RDBMS의 Table은 Collection으로 Row는

        Document로 Column은 Field로 불린다. 앞서 언급한 것처럼 미리 데이터 구조를 정해놓고 

       그 구조에 맞는 데이터만 다룰 수 있는 RDBMS와는 달리 mongoDB는 매우 유연하게 

       데이터 구조를 사용할 수 있다. 심지어는 같은 Collection안에 전혀 다른 구조의 

       Document를 넣는 것도 가능하다. 그러나 당연한 얘기겠지만 같은 Collection에는 유사한 

       Document를 다루도록 하는 것이 관리상 편하다.


RDBMS는 그 이름에서도 알 수 있듯이 Table간의 관계가 매우 중요하다. RDBMS만큼은 

       아니지만 MongoDB에서도 Collection간의 관계를 적절하게 구성을 해야 성능상의 이점을 

       누릴 수가 있다. 


       이 때 중요하게 고려해야 할 것이 바로 “쓰기 작업에서의 원자성(Atomicity of 

          Write Operations)”이다. 조금 더 이해하기 쉽게 표현하자면 mongoDB는 한 번에 하나의 

       Document 또는 Collection에서만 쓰기 작업이 가능하다는 것이다. 즉, transaction이라는 

       것을 지원하지 않는다. 바로 이런 측면이 설계 상의 중요한 고려 사항이 될 것이다.


mongoDB 모델링은 크게 2가지 구조로 나눌 수 있는데 references와 embedded이다. 각각

다음과 같이 설명할 수 있다.


  • References : RDBMS의 정규화와 같은 개념으로 볼 수 있으며 Document를 다른 Collection에               배치하여 서로 참조하도록 구성하는 개념이다.


  • Embedded : 연관성이 있는 Document를 다른 Collection에 배치하지 않고 Document 내에 Sub Document로 배치하는 방법이다.




보다 자세한 내용은 공식 사이트의 문서를 참조하도록 하고 일단 이런 기본적인 사항만을 

        고려하여 Till60의 데이터 모델링을 진행해보도록 하자.


우선 RDBMS를 기준으로 Till60에 필요한 Table을 생각해보자. 아마도 아래 정도의 

        구성이 나올 것이다(컬럼은 Till60에 필요한 것 기준이다).


  • 사용자 기본 정보 (rowid, 이름, 사용자 ID, 비밀번호, 이메일 주소 등)
  • 사용자 부가 정보 (사용자 기본 정보의 rowid, 프로필 사진, SNS 계정 등)
  • 목표 정보 (사용자 기본 정보의 rowid, rowid, 목표 제목, 목표 설명, 시작일, 종료일, 목표 상태 등)
  • 요소 정보 (목표 정보의 rowid, 요소 rowid, 요소 제목, 요소 타입, 요소 설명 등)


이 내용을 기준으로 mongoDB에서의 Collection을 다음과 같이 구성해보았다.


  • 계정을 포함한 사용자 정보를 저장할 Profile Collection
  • 목표를 구성하는 각 요소를 저장할 Elements Collection


4개의 테이블을 2개의 Collection으로 바꾸었다. 이렇게 한 이유는 다음과 같다.


사용자 기본 정보와 사용자 부가 정보는 기본적으로 1 : 1의 관계이므로 사용자 부가 

        정보는 사용자 기본 정보의 Sub Document로 하여 같은 Profile Collection에 배치 하였다

(하지만 현재 상태로는 Sub Document가 아닌 같은 레벨의 field로 사용하고 있다).


다음으로 목표 정보는 사용자 정보와는 기본적으로 1 : N의 관계이다. 사실 Till60 개발

초반에는 “선택과 집중”이라는 모토 아래 사용자 1명 당 1개의 목표만을 설정할 수 

        있도록 구상을 했지만 그렇게 되면 아무리 장기 프로젝트를 위한 시스템이라지만 한 번 

        쓰고 버리는 시스템이 될 것이기에 생각을 좀 바꾸었다(하지만 아직까지는 사용자 1명 당 

        1개의 목표만을 생성할 수 있다). 이 경우 비록 1 : N이기는 하지만 N에 해당하는 목표가 

        얼마나 많이 생성 될 것인지를 생각해보면 그리 많을 것 같지는 않다. 아주 여유있게 

        예상하여 한 명의 사용가 이 시스템을 20년 정도 사용을 하고 그 기간 동안 6개월 짜리 

        목표를 꾸준히 만든다고 해도 목표는 120개 정도. 목표 자체의 정보 량이 많지 않기 

        때문에 한번에 불러오거나 메모리에 로드되기에 부담되는 양은 아니다. 이런 이유로 목표 

        정보 역시 사용자 정보의 Sub Document로 Profile Collection에 함께 배치하기로 하였다.


결국 사용자 정보, 사용자 부가정보, 목표 정보 3개의 정보가 하나의 Document로 동일한

Profile Collection에 배치되었다. 그리고 요소 정보의 경우 목표 정보와 1 : N의 관계에 

        있지만 그 증가량이 목표 정보에 비하면 상당히 많은 수이기 때문에 목표 정보에 

        embedded로 배치하기가 어렵다고 판단되어 references로 처리하여 별도의 Collection에 

        배치하게 된 것이다.


이렇게 구성된 데이터 구조를 보면 다음과 같다(앞서 말한 것과 같이 사용자 부가 정보는 

        아직 별도의 Sub Document로 분리하지 않았다).


Profile Collection


{

    "_id" : ObjectId("584ff54a4fe35068dc44bab4"),

    "_class" : "com.mazdah.tillsixty.account.domain.Profile",

    "name" : "우형준",

    "userId" : "mazdah",

    "password" : "w00hj8928",

    "email" : "woohj70@gmail.com",

    "facebook" : "100000967897658",

    "twitter" : "@mazdah70",

    "link" : "http://mazdah.tistory.com",

    "introduction" : "평범한 아들. 평범한 남자. 평범한 가장. 평범한 개발자. 평범한 서민. 하지만 그 

                                   '평범'이 너무도 싫은 한 사람",

    "goalList" : [ 

        {

            "goalId" : "584ff54a4fe35068dc44bab4_1",

            "goalTitle" : "Project Master 개발",

            "startDate" : "2016-12-13",

            "endDate" : "2017-12-31",

            "goalDescription" : "관리자와 개발자 모두 쉽게 사용할 수 있는 프로젝트 관리 툴 개발\n

                                                      프로젝트 진행 과정을 쉽게 시각화 문서화하여 진행 상태를 직관적으로

                                                      \n확인할 수 있도록 개발",

           "goalStatus" : "O",

           "createDate" : "2016-12-13"

        }

    ]

}


Elements Collection


{

    "_id" : ObjectId("58515bb94fe35068dc44bac3"),

    "_class" : "com.mazdah.tillsixty.goal.domain.Elements",

    "userId" : "584ff54a4fe35068dc44bab4",

    "goalId" : "584ff54a4fe35068dc44bab4_1",

    "elementType" : "A",

    "title" : "메인화면 구현",

    "description" : "Parallax 스타일의 메인화면 구현",

    "createDate" : "2016-12-14"

}


아직은 개발이 진행 단계이고 변경될 여지가 많이 남아있다. 당장에 현재 화면에서는 각 

        요소별 카운트가 표시되는데 많은 수의 요소가 누적된 경우 전체 카운트를 하는 것 보다 

        Profile Collection의 Sub Document의 목표 정보에 각 요소의 전체 수를 포함시키는 것이 

        어떨까 싶다. 다만 이럴 경우 트랜잭션 처리가 필요하기 때문에 아직은 고민 중이다.


어쨌든 이번 주에는 가장 기본적인 정보만을 가지고 Till60의 데이터를 모델링 해보았다.

하지만 여전히 아직 고려되지 않은 부분들이 많아 앞으로 많은 수정을 거치게 될 것이다.

오늘의 이 글은 그저 mongoDB의 모델링을 맛보기 한데 의의를 두어야 할 것 같다.


4. 참조 (site 또는 서적)


mongoDB 문서 중 모델링에 대한 부분 : 

        https://docs.mongodb.com/manual/core/data-modeling-introduction/


5. 확인 사항 (의문 사항)


mongoDB에서의 트랜잭션 처리와 관련하여 $isolated라는 연산자가 있는데 이를 어떻게 

        사용하는지 공부를 좀 해두어야 겠다.


6. 평가


사실 워낙 작은 규모의 시스템이고 필요한 데이터도 많지 않았기에 가장 기본적인 내용만 

        확인한 후 바로 작업을 진행해보았다. 하지만 앞으로 추가될 정보들(이미지나 동영상 

        등의 미디어 정보)과 성능 또는 기능 상의 문제로 변경될 구조들(요소 count 정보 처리나 

        실제 목표를 다수 등록할 수 있게 한 이후의 처리 등)을 생각해보면 아직도 진행되어야 할 

        내용이 보여진다. 우선은 이 기본 상태에서 UI를 좀 더 손본 후 본격적으로 기능적인 

        부분을 진행해야 겠다.

블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

댓글을 달아 주세요