Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ /

무제한 배열 피하기

이 페이지의 내용

  • 예시
  • 서브세트 패턴
  • 참조 데이터
  • $lookup을 사용하여 배열 필드에서 조인하기
  • 자세히 알아보기

배열을 필드 값으로 저장하면 데이터를 포함하고 함께 액세스하는 데이터를 함께 저장할 수 있습니다. 그러나 배열 의 요소 수를 제한하지 않으면 문서가 16MB BSON 문서 크기 제한 을 초과할 수 있습니다. 배열 이 제한되지 않으면 애플리케이션 리소스에 부하가 걸리고 인덱스 성능이 저하될 수 있습니다.

전체 데이터 세트를 포함하는 대신 하위 집합을 사용하고 바인딩된 배열에 대한 참조를 사용하면 성능이 향상되고 관리 가능한 문서 크기를 유지할 수 있습니다. 데이터의 하위 집합을 지정하면 데이터에서 필요한 부분만 선택하여 작업할 수 있으므로 관련 데이터에만 집중하여 메모리 사용량과 처리 시간을 줄일 수 있습니다. 데이터를 참조할 때 외부 데이터 소스를 문서에 직접 포함하는 대신 외부 데이터 소스에 연결합니다. 이 접근 방식은 성능을 향상시키고 문서 크기를 줄입니다. 하위 집합과 참조를 사용하면 배열을 바인딩하고 날짜를 더 효율적으로 관리 수 있습니다.

서점 애플리케이션 에 대한 서평을 추적하는 다음 스키마 를 고려하세요. 초기 스키마 는 reviews 필드 에 배열 을 사용합니다.

{
title: "Harry Potter",
author: "J.K. Rowling",
publisher: "Scholastic",
reviews: [
{
user: "Alice",
review: "Great book!",
rating: 5
},
{
user: "Bob",
review: "Didn't like it!",
rating: 1
},
{
user: "Charlie",
review: "Not bad, but could be better.",
rating: 3
}
]
}

이 스키마 에서 reviews 필드 는 제한이 없는 배열 입니다. 이 책에 대한 새 검토 가 생성될 때마다 애플리케이션 은 reviews 배열 에 새 하위 문서를 추가합니다. 리뷰가 추가되면 배열 이 너무 커져 애플리케이션 리소스에 부담을 줄 수 있습니다.

이 예시 에서 서점 애플리케이션 은 책당 서평을 3개만 표시하면 됩니다. 제한이 없는 배열을 방지하려면 사용 사례 에 따라 하위 집합 디자인 패턴 또는 문서 참조 를 사용할 수 있습니다.

데이터 하위 설정은 자주 업데이트되지 않는 데이터에 빠르게 액세스 해야 하는 경우에 가장 적합합니다. 서브세트 패턴 을 사용하면 책 문서 에 세 개의 리뷰를 포함하여 한 번의 작업으로 필요한 모든 정보를 반환할 수 있습니다. 다른 리뷰는 별도의 reviews 컬렉션 에 저장됩니다. 이 스키마 설계 패턴 은 다음과 같은 이점을 제공합니다.

  • 제한이 없는 배열 제거

  • 문서 크기 제어

  • 여러 쿼리 사용 방지

books 컬렉션:

db.books.insertOne( [
{
title: "Harry Potter",
author: "J.K. Rowling",
publisher: "Scholastic",
reviews: [
{
reviewer: "Alice",
review: "Great book!",
rating: 5
},
{
reviewer: "Charlie",
review: "Didn't like it.",
rating: 1
},
{
reviewer: "Bob",
review: "Not bad, but could be better.",
rating: 3
}
],
}
] )

reviews 컬렉션:

db.reviews.insertMany( [
{
reviewer: "Jason",
review: "Did not enjoy!",
rating: 1
},
{
reviewer: "Pam",
review: "Favorite book!",
rating: 5
},
{
reviewer: "Bob",
review: "Not bad, but could be better.",
rating: 3
}
] )

이 접근 방식은 데이터를 중복하여 업데이트 비용을 발생시킵니다. 이 접근 방식은 리뷰가 자주 업데이트되지 않는 경우에 가장 좋습니다.

데이터 참조는 문서 크기를 늘리지 않고 크거나 자주 업데이트되는 데이터 세트를 관리 해야 하는 경우에 가장 적합합니다.

데이터를 참조하려면 리뷰를 별도의 컬렉션 에 저장 하고 reviews 컬렉션 의 문서에 review_id 필드 를 추가합니다. review_id 필드 를 사용하여 books 컬렉션 의 리뷰를 참조합니다.

이 접근 방식은 배열 이 제한되지 않는 문제를 해결하지만 books 컬렉션 에 대한 검토 정보를 조회 하기 위해 reviews 컬렉션 을 쿼리 해야 하므로 지연 시간 이 발생합니다. 사용 사례 에 따라 제한 없는 배열로 인해 발생하는 문제를 방지하기 위해 이러한 추가 지연 시간 은 허용 가능한 절충안이 될 수 있습니다.

books 컬렉션:

db.books.insertMany( [
{
title: "Harry Potter",
author: "J.K. Rowling",
publisher: "Scholastic",
reviews: ["review1", "review2", "review3"]
},
{
title: "Pride and Prejudice",
author: "Jane Austen",
publisher: "Penguin",
reviews: ["review4", "review5"]
}
] )

reviews 컬렉션:

db.reviews.insertMany( [
{
review_id: "review1",
reviewer: "Jason",
review: "Did not enjoy!",
rating: 1
},
{
review_id: "review2",
reviewer: "Pam",
review: "Favorite book!",
rating: 5
},
{
review_id: "review3",
reviewer: "Bob",
review: "Not bad, but could be better.",
rating: 3
},
{
review_id: "review4",
reviewer: "Tina",
review: "Amazing!",
rating: 5
},
{
review_id: "review5",
reviewer: "Jacob",
review: "A little overrated",
rating: 4,
}
] )

booksreviews 정보가 별도의 컬렉션에 저장된 경우 애플리케이션 은 데이터를 결합하기 위해 $lookup 작업을 수행해야 합니다.

다음 집계 작업은 이전 예시 의 booksreviews 컬렉션 을 조인합니다.

db.books.aggregate( [
{
$lookup: {
from: "reviews",
localField: "reviews",
foreignField: "review_id",
as: "reviewDetails"
}
}
] )

이 연산은 다음을 반환합니다:

[
{
_id: ObjectId('665de81eeda086b5e22dbcc9'),
title: 'Harry Potter',
author: 'J.K. Rowling',
publisher: 'Scholastic',
reviews: [ 'review1', 'review2', 'review3' ],
reviewDetails: [
{
_id: ObjectId('665de82beda086b5e22dbccb'),
review_id: 'review1',
reviewer: 'Jason',
review: 'Did not enjoy!',
rating: 1
},
{
_id: ObjectId('665de82beda086b5e22dbccc'),
review_id: 'review2',
reviewer: 'Pam',
review: 'Favorite book!',
rating: 5
},
{
_id: ObjectId('665de82beda086b5e22dbccd'),
review_id: 'review3',
reviewer: 'Bob',
review: 'Not bad, but could be better.',
rating: 3
} ]
},
{
_id: ObjectId('665de81eeda086b5e22dbcca'),
title: 'Pride and Prejudice',
author: 'Jane Austen',
publisher: 'Penguin',
reviews: [ 'review4', 'review5' ],
reviewDetails: [
{
_id: ObjectId('665de82beda086b5e22dbcce'),
review_id: 'review4',
reviewer: 'Tina',
review: 'Amazing!',
rating: 5
},
{
_id: ObjectId('665de82beda086b5e22dbccf'),
review_id: 'review5',
reviewer: 'Jacob',
review: 'A little overrated',
rating: 4
} ]
}
]

이 예시 에서 $lookup 작업은 책 문서 의 reviews 배열 과 리뷰 문서의 review_id 필드 를 사용하여 books 컬렉션 을 reviews 컬렉션 과 조인합니다. reviewDetails 문서 에는 결합된 데이터가 저장됩니다.

돌아가기

스키마 설계 안티패턴