문서 메뉴

문서 홈애플리케이션 개발MongoDB 매뉴얼

포함된 문서로 일대다 관계 모델링하기

이 페이지의 내용

  • 개요
  • 임베디드 문서 패턴
  • 서브세트 패턴

이 페이지에서는 내장된 문서 를 사용하여 연결된 데이터 간의 일대다 관계를 설명하는 Realm 데이터 모델에 대해 설명합니다. 연결된 데이터를 단일 문서에 포함하면 데이터 획득에 필요한 읽기 작업 수를 줄일 수 있습니다. 일반적으로 애플리케이션이 읽기 작업을 한 번 실행할 때 필요한 모든 정보를 수신하도록 스키마를 구성해야 합니다.

고객과 여러 주소 관계를 매핑하는 다음 예제를 살펴보겠습니다. 이 예는 다른 데이터 엔터티의 컨텍스트에서 많은 데이터 엔터티를 확인해야 하는 경우 참고보다 포함이 더 유리하다는 것을 보여줍니다. patronaddress 데이터 간의 일대다 관계에서 patron 에는 여러 개의 address 엔터티가 있습니다.

정규화된 데이터 모델에서 address 문서에는 patron 문서에 대한 참조가 포함되어 있습니다.

// patron document
{
_id: "joe",
name: "Joe Bookreader"
}
// address documents
{
patron_id: "joe", // reference to patron document
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
{
patron_id: "joe",
street: "1 Some Other Street",
city: "Boston",
state: "MA",
zip: "12345"
}

애플리케이션에서 name 정보가 포함된 address 데이터를 자주 조회하는 경우 애플리케이션에서 참고를 해결하기 위해 여러 번의 쿼리를 실행해야 합니다. 더 최적의 스키마는 다음 문서에서와 같이 address 데이터 엔터티를 patron 데이터에 포함하는 것입니다.

{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}

포함된 데이터 모델을 사용하면 애플리케이션에서 한 번의 쿼리로 완전한 고객 정보를 조회할 수 있습니다.

내장된 문서 패턴 의 잠재적인 문제는 특히 내장된 필드가 바인딩되지 않은 경우 큰 문서로 이어질 수 있다는 점입니다. 이 경우 포함된 전체 데이터 세트 대신 서브세트 패턴을 사용하여 애플리케이션에 필요한 데이터에만 액세스할 수 있습니다.

제품에 대한 리뷰 목록이 있는 전자상거래 사이트를 예로 들어 보겠습니다.

{
"_id": 1,
"name": "Super Widget",
"description": "This is the most useful item in your toolbox.",
"price": { "value": NumberDecimal("119.99"), "currency": "USD" },
"reviews": [
{
"review_id": 786,
"review_author": "Kristina",
"review_text": "This is indeed an amazing widget.",
"published_date": ISODate("2019-02-18")
},
{
"review_id": 785,
"review_author": "Trina",
"review_text": "Nice product. Slow shipping.",
"published_date": ISODate("2019-02-17")
},
...
{
"review_id": 1,
"review_author": "Hans",
"review_text": "Meh, it's okay.",
"published_date": ISODate("2017-12-06")
}
]
}

리뷰는 시간 역순으로 정렬됩니다. 사용자가 제품 페이지를 방문하면 애플리케이션이 가장 최근의 리뷰 10개를 로드합니다.

모든 리뷰를 제품과 함께 저장하는 대신, 컬렉션을 두 개로 분할할 수 있습니다.

  • product collection은 제품의 가장 최근 리뷰 10개를 포함하여 각 제품에 대한 정보를 저장합니다.

    {
    "_id": 1,
    "name": "Super Widget",
    "description": "This is the most useful item in your toolbox.",
    "price": { "value": NumberDecimal("119.99"), "currency": "USD" },
    "reviews": [
    {
    "review_id": 786,
    "review_author": "Kristina",
    "review_text": "This is indeed an amazing widget.",
    "published_date": ISODate("2019-02-18")
    }
    ...
    {
    "review_id": 777,
    "review_author": "Pablo",
    "review_text": "Amazing!",
    "published_date": ISODate("2019-02-16")
    }
    ]
    }
  • review collection에는 모든 리뷰가 저장됩니다. 각 리뷰에는 리뷰가 작성된 제품에 대한 참고가 포함되어 있습니다.

    {
    "review_id": 786,
    "product_id": 1,
    "review_author": "Kristina",
    "review_text": "This is indeed an amazing widget.",
    "published_date": ISODate("2019-02-18")
    }
    {
    "review_id": 785,
    "product_id": 1,
    "review_author": "Trina",
    "review_text": "Nice product. Slow shipping.",
    "published_date": ISODate("2019-02-17")
    }
    ...
    {
    "review_id": 1,
    "product_id": 1,
    "review_author": "Hans",
    "review_text": "Meh, it's okay.",
    "published_date": ISODate("2017-12-06")
    }

가장 최근 리뷰 10개를 product collection에 저장하면 product collection 호출 시 전체 데이터의 필수 하위 집합만 반환됩니다. 사용자가 추가 리뷰를 보고자 하는 경우 애플리케이션은 review collection을 호출합니다.

데이터를 분할할 위치를 고려할 때는 애플리케이션이 가장 먼저 로드하는 컬렉션에 가장 자주 액세스하는 데이터가 포함되어야 합니다. 이 예에서 ‑스키마는 애플리케이션에서 표시되는 리뷰 수의 기본값인 10개로 리뷰를 분할합니다.

다음도 참조하세요.

서브세트 패턴을 사용하여 컬렉션 간의 일대일 관계를 모델링하는 방법을 알아보려면 내장된 문서로 일대일 관계 모델링하기를 참조하세요.

자주 액세스하는 데이터가 포함된 작은 문서를 사용하면 작업 세트의 전체 크기를 줄일 수 있습니다. 문서 크기가 작아지면 애플리케이션이 가장 자주 액세스하는 데이터의 읽기 성능이 향상됩니다.

그러나 서브세트 패턴은 데이터 중복을 초래합니다. 이 예제에서는 product collection과 reviews collection 모두에서 리뷰가 유지 관리됩니다. 각 collection 간에 리뷰의 일관성을 유지하려면 추가 단계를 수행해야 합니다. 예를 들어, 고객이 리뷰를 편집할 때 애플리케이션은 product collection을 업데이트하는 것과 reviews collection을 업데이트하는 두 가지 쓰기 작업을 수행해야 할 수 있습니다.

또한 애플리케이션에 로직을 구현하여 product 컬렉션의 리뷰가 항상 해당 제품에 대한 최신 리뷰 10개가 되도록 해야 합니다.

제품 리뷰 외에도 서브세트 패턴도 저장에 적합할 수 있습니다.

  • 블로그 포스트의 댓글 - 가장 최근 댓글 또는 가장 높은 평점의 댓글을 기본값으로 표시하려는 경우.

  • 영화의 출연진 - 가장 큰 역할을 맡은 출연진을 기본값으로 표시하려는 경우

← 포함된 문서로 일대일 관계 모델링하기