보관 패턴
수년 동안의 기록 데이터를 저장 해야 하는 경우, 가장 오래된 데이터를 더 최근 데이터와 동일한 데이터베이스 에 저장하면 특히 오래된 데이터에 자주 액세스할 필요가 없는 경우 성능에 부정적인 영향 수 있습니다. 대신 이전 데이터를 보관하고 해당 데이터를 별도의 저장 위치 로 이동하도록 스키마 를 설계할 수 있습니다.
이 작업에 대하여
보관된 데이터를 저장 방법에는 여러 가지 옵션이 있습니다. 예시 를 들어 다음을 수행할 수 있습니다.
데이터를 Amazon S3와 같은 외부 파일 저장 로 이동합니다.
데이터를 더 저렴한 별도의 클러스터 로 이동합니다.
데이터를 동일한 클러스터 의 별도 컬렉션 으로 이동합니다.
대부분의 경우 비용 과 성능 면에서 데이터를 외부 파일 저장 로 이동하는 것이 가장 좋습니다. 사용 사례 에 따라 외부 파일 저장 사용할 수 없는 경우 데이터를 별도의 클러스터 또는 컬렉션 으로 이동하는 것이 좋습니다.
데이터 보관을 위한 팁
데이터 보관 디자인 패턴 구현 전에 다음 권장사항 검토 .
보관된 데이터는 다른 컬렉션에 대한 참조를 사용하는 대신 내장된 데이터 모델 사용해야 합니다. 보관된 데이터를 쿼리 때 데이터의 모든 관련 구성 요소는 동일한 시간에 나온 것이어야 합니다. 데이터를 임베딩하면 쿼리가 관련 데이터를 함께 반환합니다.
문서의 보존 기간은 단일 필드 에 포함되어야 합니다.
만료되지 않거나 아카이브로 이동하지 않아야 하는 문서가 있는 경우 문서 보존 기간을
keep forever
또는 유사한 문자열로 설정하다 문서 활성 컬렉션 에 유지되어야 함을 나타냅니다.MongoDB Atlas 자주 액세스하지 않는 데이터를 Atlas cluster 에서 cloud 객체 저장 의 MongoDB 관리형 읽기 전용 연합 데이터베이스 인스턴스로 이동하는 Online 보관 제공합니다.
Scenario
이 예시 에서 전자상거래 저장 5년 이상 전에 발생한 판매에 대한 데이터를 보관하려고 합니다. 초기 데이터 세트에는 모든 판매가 포함되며 이전 판매에 대한 문서는 별도의 컬렉션 으로 이동됩니다.
단계
샘플 데이터 채우기
db.sales.insertMany( [ { customer_name: "Hiroshi Tanaka", products: [ { product_id: "P1001", name: "Wireless Headphones", quantity: 1, price: 59.99 }, { product_id: "P1002", name: "Phone Charger", quantity: 2, price: 14.99 } ], total_amount: 89.97, date: ISODate("2025-01-30T10:15:00Z") }, { customer_name: "Aisha Khan", products: [ { product_id: "P1003", name: "Laptop", quantity: 1, price: 899.99 } ], total_amount: 899.99, date: ISODate("2018-11-20T15:45:00Z") // Over 5 years ago }, { customer_name: "Fatima Al-Farsi", products: [ { product_id: "P1006", name: "Gaming Mouse", quantity: 1, price: 49.99 }, { product_id: "P1007", name: "Mechanical Keyboard", quantity: 1, price: 129.99 } ], total_amount: 179.98, date: ISODate("2017-06-15T12:00:00Z") // Over 5 years ago }, { customer_name: "Nguyen Minh", products: [ { product_id: "P1008", name: "Bluetooth Speaker", quantity: 2, price: 39.99 } ], total_amount: 79.98, date: ISODate("2025-01-26T09:20:00Z") } ] )
오래된 문서를 보관하는 스크립트 작성
참고
다음 스크립트 MongoDB Shell 구문을 사용합니다. 운전자에 대한 집계 및 쿼리 구문을 확인하려면 운전자 설명서를 참조하세요.
// Set a variable to five years before the time that the script runs const fiveYearsAgo = new Date(); fiveYearsAgo.setFullYear(fiveYearsAgo.getFullYear() - 5); // Write old sales to the 'archived_sales' collection const writeOldSalesPipeline = [ { $match: { date: { $lt: fiveYearsAgo } } }, { $merge: { into: { db: "test", coll: "archived_sales", }, on: "_id" } } ] db.sales.aggregate(writeOldSalesPipeline) // Delete old sales from the active 'sales' collection try { db.sales.deleteMany( { date : { $lt: fiveYearsAgo } } ); } catch (e) { print (e); }
결과
스크립트 실행 하면 sales
컬렉션 5년 이상 전에 발생한 판매가 더 이상 포함되지 않습니다.
db.sales.find()
출력:
[ { _id: ObjectId('679ced18fa29d32ca7d1abab'), customer_name: 'Hiroshi Tanaka', products: [ { product_id: 'P1001', name: 'Wireless Headphones', quantity: 1, price: 59.99 }, { product_id: 'P1002', name: 'Phone Charger', quantity: 2, price: 14.99 } ], total_amount: 89.97, date: ISODate('2025-01-30T10:15:00.000Z') }, { _id: ObjectId('679ced18fa29d32ca7d1abae'), customer_name: 'Nguyen Minh', products: [ { product_id: 'P1008', name: 'Bluetooth Speaker', quantity: 2, price: 39.99 } ], total_amount: 79.98, date: ISODate('2025-01-26T09:20:00.000Z') } ]
이제 이전 판매가 archived_sales
컬렉션 에 존재합니다.
db.archived_sales.find()
출력:
[ { _id: ObjectId('679ced18fa29d32ca7d1abac'), customer_name: 'Aisha Khan', products: [ { product_id: 'P1003', name: 'Laptop', quantity: 1, price: 899.99 } ], total_amount: 899.99, date: ISODate('2018-11-20T15:45:00.000Z') }, { _id: ObjectId('679ced18fa29d32ca7d1abad'), customer_name: 'Fatima Al-Farsi', products: [ { product_id: 'P1006', name: 'Gaming Mouse', quantity: 1, price: 49.99 }, { product_id: 'P1007', name: 'Mechanical Keyboard', quantity: 1, price: 129.99 } ], total_amount: 179.98, date: ISODate('2017-06-15T12:00:00.000Z') } ]