Docs Menu

보관 패턴

수년 동안의 기록 데이터를 저장 해야 하는 경우, 가장 오래된 데이터를 더 최근 데이터와 동일한 데이터베이스 에 저장하면 특히 오래된 데이터에 자주 액세스할 필요가 없는 경우 성능에 부정적인 영향 수 있습니다. 대신 이전 데이터를 보관하고 해당 데이터를 별도의 저장 위치 로 이동하도록 스키마 를 설계할 수 있습니다.

보관된 데이터를 저장 방법에는 여러 가지 옵션이 있습니다. 예시 를 들어 다음을 수행할 수 있습니다.

  • 데이터를 Amazon S3와 같은 외부 파일 저장 로 이동합니다.

  • 데이터를 더 저렴한 별도의 클러스터 로 이동합니다.

  • 데이터를 동일한 클러스터 의 별도 컬렉션 으로 이동합니다.

대부분의 경우 비용 과 성능 면에서 데이터를 외부 파일 저장 로 이동하는 것이 가장 좋습니다. 사용 사례 에 따라 외부 파일 저장 사용할 수 없는 경우 데이터를 별도의 클러스터 또는 컬렉션 으로 이동하는 것이 좋습니다.

데이터 보관 디자인 패턴 구현 전에 다음 권장사항 검토 .

  • 보관된 데이터는 다른 컬렉션에 대한 참조를 사용하는 대신 내장된 데이터 모델 사용해야 합니다. 보관된 데이터를 쿼리 때 데이터의 모든 관련 구성 요소는 동일한 시간에 나온 것이어야 합니다. 데이터를 임베딩하면 쿼리가 관련 데이터를 함께 반환합니다.

  • 문서의 보존 기간은 단일 필드 에 포함되어야 합니다.

  • 만료되지 않거나 아카이브로 이동하지 않아야 하는 문서가 있는 경우 문서 보존 기간을 keep forever 또는 유사한 문자열로 설정하다 문서 활성 컬렉션 에 유지되어야 함을 나타냅니다.

  • MongoDB Atlas 자주 액세스하지 않는 데이터를 Atlas cluster 에서 cloud 객체 저장 의 MongoDB 관리형 읽기 전용 연합 데이터베이스 인스턴스로 이동하는 Online 보관 제공합니다.

이 예시 에서 전자상거래 저장 5년 이상 전에 발생한 판매에 대한 데이터를 보관하려고 합니다. 초기 데이터 세트에는 모든 판매가 포함되며 이전 판매에 대한 문서는 별도의 컬렉션 으로 이동됩니다.

1
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")
}
] )
2

참고

다음 스크립트 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')
}
]