무제한 배열 피하기
배열을 필드 값으로 저장하면 데이터를 포함하고 함께 액세스하는 데이터를 함께 저장할 수 있습니다. 그러나 배열 의 요소 수를 제한하지 않으면 문서가 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, } ] )
$lookup을 사용하여 배열 필드에서 조인하기
books
및 reviews
정보가 별도의 컬렉션에 저장된 경우 애플리케이션 은 데이터를 결합하기 위해 $lookup
작업을 수행해야 합니다.
다음 집계 작업은 이전 예시 의 books
및 reviews
컬렉션 을 조인합니다.
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
문서 에는 결합된 데이터가 저장됩니다.