내장된 문서로 일대일 관계 모델링하기
이 페이지의 내용
개요
이 페이지에서는 내장된 문서를 사용하여 연결된 데이터 간의 일대일 관계 를 설명하는 데이터 모델 에 대해 설명합니다. 연결된 데이터를 단일 문서 에 포함하면 데이터를 얻는 데 필요한 읽기 작업 수를 줄일 수 있습니다. 일반적으로 애플리케이션 이 한 번의 읽기 작업으로 필요한 모든 정보를 받을 수 있도록 스키마 를 구조화해야 합니다.
임베디드 문서 패턴
고객과 주소 관계를 매핑하는 다음 예제를 살펴보겠습니다. 이 예는 다른 데이터 엔터티의 컨텍스트에서 하나의 데이터 엔터티를 확인해야 하는 경우 참고보다 포함이 더 유리하다는 것을 보여줍니다. patron
와 address
데이터 간의 일대일 관계에서 address
은 patron
에 속합니다.
Realm 데이터 모델에서 address
문서에는 patron
문서에 대한 참고가 포함되어 있습니다.
// patron document { _id: "joe", name: "Joe Bookreader" } // address document { patron_id: "joe", // reference to patron document street: "123 Fake Street", city: "Faketon", state: "MA", zip: "12345" }
name
정보로 address
데이터를 자주 조회하는 경우 참조를 사용하면 애플리케이션에서 참조를 해결하기 위해 여러 쿼리를 실행해야 합니다. 더 나은 데이터 모델은 다음 문서에서와 같이 address
데이터를 patron
데이터에 포함하는 것입니다.
{ _id: "joe", name: "Joe Bookreader", address: { street: "123 Fake Street", city: "Faketon", state: "MA", zip: "12345" } }
포함된 데이터 모델을 사용하면 애플리케이션에서 한 번의 쿼리로 완전한 고객 정보를 조회할 수 있습니다.
서브세트 패턴
내장된 문서 패턴 의 잠재적 문제점은 애플리케이션에 필요하지 않은 필드를 포함하는 큰 문서로 이어질 수 있다는 것입니다. 이 불필요한 데이터로 인해 서버에 추가 부하가 발생하고 읽기 작업 속도가 느려질 수 있습니다. 대신 서브세트 패턴을 사용하여 한 번의 데이터베이스 호출에서 가장 자주 액세스되는 데이터의 서브세트를 조회할 수 있습니다.
영화에 대한 정보를 표시하는 애플리케이션을 예로 들어 보겠습니다. 데이터베이스에는 다음 스키마를 가진 movie
collection이 포함되어 있습니다.
{ "_id": 1, "title": "The Arrival of a Train", "year": 1896, "runtime": 1, "released": ISODate("01-25-1896"), "poster": "http://ia.media-imdb.com/images/M/MV5BMjEyNDk5MDYzOV5BMl5BanBnXkFtZTgwNjIxMTEwMzE@._V1_SX300.jpg", "plot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, ...", "fullplot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, the line dissolves. The doors of the railway-cars open, and people on the platform help passengers to get off.", "lastupdated": ISODate("2015-08-15T10:06:53"), "type": "movie", "directors": [ "Auguste Lumière", "Louis Lumière" ], "imdb": { "rating": 7.3, "votes": 5043, "id": 12 }, "countries": [ "France" ], "genres": [ "Documentary", "Short" ], "tomatoes": { "viewer": { "rating": 3.7, "numReviews": 59 }, "lastUpdated": ISODate("2020-01-09T00:02:53") } }
현재 movie
컬렉션에는 fullplot
및 등급 정보와 같이 애플리케이션에서 영화에 대한 간단한 개요를 표시하는 데 필요하지 않은 여러 필드가 포함되어 있습니다. 모든 영화 데이터를 단일 collection에 저장하는 대신 collection을 두 개의 collection으로 분할할 수 있습니다.
movie
collection에는 영화에 대한 기본 정보가 포함되어 있습니다. 애플리케이션이 기본적으로 로드하는 데이터는 다음과 같습니다.// movie collection { "_id": 1, "title": "The Arrival of a Train", "year": 1896, "runtime": 1, "released": ISODate("1896-01-25"), "type": "movie", "directors": [ "Auguste Lumière", "Louis Lumière" ], "countries": [ "France" ], "genres": [ "Documentary", "Short" ], } movie_details
collection에는 각 영화에 대한 액세스 빈도가 낮은 추가 데이터가 포함되어 있습니다.// movie_details collection { "_id": 156, "movie_id": 1, // reference to the movie collection "poster": "http://ia.media-imdb.com/images/M/MV5BMjEyNDk5MDYzOV5BMl5BanBnXkFtZTgwNjIxMTEwMzE@._V1_SX300.jpg", "plot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, ...", "fullplot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, the line dissolves. The doors of the railway-cars open, and people on the platform help passengers to get off.", "lastupdated": ISODate("2015-08-15T10:06:53"), "imdb": { "rating": 7.3, "votes": 5043, "id": 12 }, "tomatoes": { "viewer": { "rating": 3.7, "numReviews": 59 }, "lastUpdated": ISODate("2020-01-29T00:02:53") } }
이 방법을 사용하면애플리케이션이 가장 일반적인 요청을 처리하기 위해 필요한 데이터 읽기 횟수가 줄어들기 때문에 읽기 성능이 향상됩니다. 애플리케이션은 필요한 경우 추가 데이터베이스 호출을 수행하여 액세스 빈도가 낮은 데이터를 가져올 수 있습니다.
팁
데이터를 분할할 위치를 고려할 때는 애플리케이션이 가장 먼저 로드하는 컬렉션에 가장 자주 액세스하는 데이터가 포함되어야 합니다.
하위 집합 패턴의 장단점
자주 액세스하는 데이터가 포함된 작은 문서를 사용하면 작업 세트의 전체 크기를 줄일 수 있습니다. 문서 크기가 작아지면 읽기 성능이 향상되고 애플리케이션에 더 많은 메모리를 사용할 수 있습니다.
그러나 애플리케이션과 애플리케이션이 데이터를 로드하는 방식을 이해하는 것이 중요합니다. 데이터를 여러 collection으로 부적절하게 분할하면 애플리케이션이 데이터베이스를 여러 번 방문해야 하고 필요한 모든 데이터를 조회하기 위해 JOIN
작업에 의존하게 됩니다.
또한 데이터를 여러 개의 작은 컬렉션으로 분할하면 어떤 데이터가 어떤 컬렉션에 저장되어 있는지 추적하기 어려워져 데이터베이스 유지 관리에 필요한 시간이 늘어날 수 있습니다.