2장. Mongoose 를 통한 MongoDB 연동 실습

MongoDB의 소개

MongoDB 는 C++ 로 작성된 문서(document)지향적 데이터베이스이며, 뛰어난 확장성과 성능을 자랑합니다. 또한, 현존하는 NoSQL 데이터베이스중에서 1위를 유지하고있기도 합니다.

흔히 NoSQL 이라고 해서, SQL 이 없는 데이터베이스이구나, 라고 생각 할 수도 있습니다. 하지만, 이는 잘못된 이해이며, 실은 Not Only SQL 의 약자입니다. 기존의 RDBMS(관계형 데이터베이스) 의 한계를 극복하기 위하여 만들어진 새로운 형태의 데이터저장소이며, 이는 MySQL, PostgreSQL 등처럼 관계형 데이터베이스가 아니므로, 고정된 스키마를 가지고있지 않으며, JOIN 같은것이 존재하지 않습니다.

문서 (document) ?

여기서 말하는 문서는, RDBMS 의 record 와의 비슷한 개념입니다. 데이터베이스의 데이터 구조는 한개 이상의 key-value 쌍으로 이뤄져있습니다.

MongoDB 에서는, 데이터베이스를 어떻게 담는지 한번 살펴봅시다.

{
    "_id": ObjectId("5099803df3f4948bd2f98391"),
    "username": "velopert",
    "name": { first: "M.J.", last: "Kim" }
}

각 문서는, _id 라는 고유값을 가지게 되는데 시간/머신ID/프로세스ID/순차번호 로 이뤄져있어서 값의 고유함을 보장 할 수 있습니다.

문서는 동적인 스키마를 가질 수 있습니다. 여러 문서들이 들어있는곳을 컬렉션 이라고 부르는데요, 기존의 RDBMS 에서는 테이블이란 개념을 사용하고, 각 테이블마다 같은 스키마를 가져야합니다. 만약에 데이터 구조를 바꿔야한다면, 전체 데이터를 바꿔주어야하지요.

하지만, MongoDB 에서는 한 컬렉션에서 다른 스키마를 가지고 있을 수 있습니다.

예를들어서, 다음 데이터들이 한 컬렉션안에 공존 할 수있습니다.

{ 
    "_id": ObjectId("594948a081ad6e0ea526f3f5"),
    "username": "velopert"
},
{ 
    "_id": ObjectId("59494fca81ad6e0ea526f3f6"),
    "username": "nakim",
    "phone": "010-3333-6666"
}

예를들어서, 처음에는 데이터에 전화번호가 필요없었는데 나중에 필요해졌다고 가정을 해봅시다. RDBMS 에서는, 한 테이블에선 모든 데이터가 같은 스키마를 가져야하기 때문에, 기존 데이터들도 다 하나하나 수정을 해줬어야하는데, MongoDB 에서는 컬렉션안의 데이터들은 같은 스키마를 가질 필요가 없으므로 그냥 넣어주면 됩니다. 그리고, 만약에 필요한 데이터가 없으면 유저한테서 새로 입력을 받는 로직을 작성하면 되겠지요.

스키마 디자인

기존 RDBMS 에서 블로그를 위한 데이터 스키마를 디자인한다면, 각 포스트, 그리고 덧글마다 테이블을 만들고 필요에 따라 JOIN 해서 사용하는게 일반적입니다.

하지만, MongoDB 에서는 데이터 스키마를 디자인 할때는 한 문서에 최대한 많은 데이터를 넣는것이 관습입니다. 즉, 포스트 내부에 덧글 배열을 내부에 넣는것이죠. 이를 서브다큐먼트 라고 부르며, 서브다큐먼트도 일반 문서를 다루는 것 처럼 쿼리를 할 수 있습니다.

한 문서에는 16MB 만큼의 데이터를 넣을 수 있습니다. 100자의 덧글이라면 대략 0.24KB 를 차지하는데요, 16MB 는 16,384KB 이고, 이를 계산하면 한 문서에는 대략 68,000 가량의 덧글을 작성 할 수 있습니다.

만약에, 이 용량을 초과 할 가능성이 있으면, 컬렉션을 분리하는것이 좋습니다.

다른 예제로는, 책에 대한 정보를 데이터베이스에 넣는데, RDBMS 에서는 책의 정보와, 저자의 정보를 따로 books, authors 이렇게 다른 테이블에 넣는게 일반적이지만, MongoDB 에서는 저자의 정보를 books 문서 내부에 서브다큐먼트로 넣는것이 좋습니다.

이렇게 함으로써, 한번의 쿼리로, 원하는 정보를 바로 불러올 수 있습니다. 하지만 저자의 정보가 자주 바뀔 수 있다면, 컬렉션을 따로 분리시키고 authors 문서의 id 를 books 에 넣어줍니다.

이렇게 하면, 책의 모든 정보를 가져오기위해서 두번 쿼리를 하게되지만, 데이터베이스 인덱싱이 잘 되어있다면, 성능상으로는 RDBMS 에서의 JOIN 과 큰 차이가 나지 않습니다.

results matching ""

    No results matching ""