MongoDB 공부 및 적용 : 스키마 설정 및 embedding/referencing

정재헌·2023년 3월 25일
0

Database

목록 보기
3/6

MongoDB를 이용한 프로젝트를 진행하게 되어, MongoDB에 대한 공부를 함께 진행 중에 있다. 처음에는 좀 더 편하게 이해하기 위하여 MongoDB를 사용한 회사들의 기술 블로그를 바탕으로 공부를 하였으며, 이제는 좀 더 깊은 이해를 위해서 공식 문서를 바탕으로 블로그를 작성해보고자 한다.

첫 번째 MongoDB 블로그에서, MongoDB 기본 설정과 MongoDB의 장점들에 대허 간략하게 알아 보았다. 오늘은 두 번째 시간으로, MongoDB에서 이야기하는 좋은 데이터 모델링과 MongoDB 내 relation type인 embedding과 referencing에 대해서 알아보고자 한다.

좋은 데이터 모델링이란?

  • 데이터를 다루기에 용이하다.
  • 효율적인 query가 가능하다.
  • 효율적인 memory, CPU 사용이 가능하다.
  • 비용(데이터 CRUD, 개발자 생산성, 기회 비용 등)을 줄일 수 있다.

위의 4가지가, MongoDB에서 이야기하는 좋은 데이터 모델링의 장점들이다. MongoDB에서는 애플리케이션 서비스의 필요에 따라 embedding과 referencing을 통해 정규화하는 것을 권장한다. 이를 통해, 자원을 최적으로 저장, 조회 및 사용할 수 있다고 한다.

Relation types in MongoDB

MongoDB에서 데이터를 다루는 데 가장 중요하게 생각하는 것은 바로, '함께 액세스하는 데이터는 함께 저장하도록 해야 한다'이다. 그렇기 때문에, 기본적으로 MongoDB는 함께 액세스하는 데이터의 경우에 하나의 document 형태로 저장되기를 권장한다.

하지만, 경우에 따라서는 데이터를 구조화해야 하는데, 그 기준은 바로 애플리케이션에 달려 있다. 따라서, MongoDB는 애플리케이션이 데이터를 쿼리하고 업데이트하는 방식과 일치하도록 데이터를 구조화해야 한다고 이야가 한다. 다음은 MongoDB에서 정의한 relation types에 대한 내용이다.

One-to-One

A relationship where a data entity in one set is connected to exactly one data entity in another set.
ex) movie & director

One-to-Many

A relationship where a data entity in one set is connected to any number of data entities in another set.
ex) movie & casts

Many-to-Many

A relationship where any number of data entities in one set are connected to any number of data entities in another set.

MongoDB 관계 모델링 방법 : embedding / referencing

embedding
We take related data and insert it into our document.

referencing
We refer to documents in another collection in our document.

개인 정보 중 핸드폰 번호, 긴급 번호 등을 다룬다고 가정해보자. 데이터의 모습은 아래와 같을 것이다.

{
	_id: ObjectId('123asaeas12123'),
    name: 'John',
    email: 'john@email.com',
    city: 'LA',
    home_number: '111-222-3321',
    phone_number: '112-222-4444',
    emergency_number: '112-455-1234'
}
{
	_id: ObjectId('123asaeas12123'),
    name: 'John',
    email: 'john@email.com',
    city: 'LA',
    number: ['111-222-3321', '112-222-4444', '112-455-1234']
}
{
	_id: ObjectId('123asaeas12123'),
    name: 'John',
    email: 'john@email.com',
    city: 'LA',
    contact_number: 
    	{
    	'number': '111-222-3321', 'type': 'home', 
        'number': '112-222-4444', 'type': 'phone',
        'number': '112-455-1234', 'type': 'emergency'
        }
}

처음에는 home_number / phone_numer / emergency_number를 각각 입력하였지만, 정규화를 통해서 contact_number라는 key 안에 value들이 입력된 것을 볼 수 있다. 이는 절대적인 것은 아니며, 애플리케이션의 특성을 고려하여야 함을 잊지 말자.

Embedding data in documents

MongoDB에서는 쿼리를 단순화하고 전반적인 쿼리 성능을 향상시키기 위해 embedding 사용을 권장한다. 계속 강조하지만, MongoDB에서는 함께 액세스 하는 데이터는 함께 저장해야 한다는 것이 철칙이다. 이는 데이터 읽기에 효율적이며 한 번의 write로 업데이트가 가능하기 때문이다.

고려해야 할 문제점

  • 너무 큰 데이터가 될 경우에는 embedding을 지양한다. (메모리 부하로 인한 성능 저하 우려)
  • 데이터가 끊임없이 추가되는 경우, 제한 용량(BSON)을 초과할 수 있다.

Referencing data in documents

references
Save the _id field of one document in another document as a link between the two
-> data normalization

이를 통해, 데이터 중복을 방지할 수 있으며, 더 작은 document가 생성된다고 보면 된다. 하지만 이로 인해 추가 쿼리 작업이 발생하여 비용이 늘어난다.

MongoDB에서는 왜 그렇게 '함께 액세스, 함께 저장'을 강조하는 것일까?

그 이유는 아래와 같다.

Optimum efficiency of

  • Query result times
  • Memory usage
  • CPU usage
  • Storage

Schema anti-pattern을 위핸 MongoDB tools in Atlas

  • Data Explorer
  • Performance Advisor

다음과 같은 경우 Schema anti-pattern에 해당 된다고 한다.

  • 대규모 배열
  • 대량의 collection
  • 큰 규모의 document(용량 초과/성능 저하 등)
  • 불필요한 index
  • index가 없는 쿼리
  • 참조가 많이 이뤄지는 경우

이를 방지하기 위해 MongoDB Atlas에서는 데이터가 어떻게 저장되고 사용되는지에 대해 간략하게 확인할 수 있으며, anti-pattern이라는 항목을 통해서 어떻게 수정해야 되는지 수정 사항에 대해서도 제공해주고 있다.

<출처>
https://learn.mongodb.com/learn/learning-path/mongodb-nodejs-developer-path

profile
백엔드 개발자

0개의 댓글