본 문서는 "MongoDB Developer Center Articles"를 참고하여 작성되었습니다.
🔗 https://www.mongodb.com/developer/products/mongodb/polymorphic-pattern/
The Polymorphic Pattern
- 모든 컬렉션 문서가 유사하지만 완전히 동일하지 않은 구조를 가지고 있을 때
- 문서가 동일한 컬렉션에 있더라도 각 선수에 대한 저장된 데이터가 동일할 필요는 없음
{
"sport": "ten_pin_bowling",
"athlete_name": "Earl Anthony",
"career_earnings": { value: NumberDecimal("1441061"), currency: "USD"},
"300_games": 25,
"career_titles": 43,
"other_sports": "baseball"
},
{
"sport": "tennis",
"athlete_name": "Martina Navratilova",
"career_earnings": { value: NumberDecimal("216226089"), currency: "USD"},
"event": {
"type": "singles",
"career_tournaments": 390,
"career_titles": 167
}
}
The Shema Versioning Pattern
- MongoDB가 서로 다른 형태의 문서를 동일한 데이터베이스 컬렉션에 존재할 수 있도록 지원하는 특징을 활용
- 동일한 필드에 대해 서로 다른 필드 또는 서로 다른 필드 유형을 가진 문서가 공존할 수 있음
{
"_id": "<ObjectId>",
"name": "Anakin Skywalker",
"home": "503-555-0000",
"work": "503-555-0010"
},
{
"_id": "<ObjectId>",
"name": "Anakin Skywalker",
"home": "503-555-0100",
"work": "503-555-0110",
"mobile": "503-555-0120"
},
{
"_id": "<ObjectId>",
"schema_version": "2",
"name": "Anakin Skywalker (Retired)",
"contact_method": [
{ "home": "503-555-0210" },
{ "work": "503-555-0220" },
{ "twitter": "@anakinskywalker" },
{ "skype" : "AlwaysWithYou" }
]
}
The Attribute Pattern
다음과 같은 경우에 적합
- 큰 문서가 많은 유사한 필드를 가지고 있지만 일부 필드는 공통 특성을 공유하며 해당 필드의 하위 집합에서 정렬 혹은 쿼리를 수행
- 정렬해야 하는 필드가 문서의 작은 하우 집합에서만 발견
- 문서 내에서 위의 두 가지 조건이 모두 충족되는 경우
➡️ 하위 집합에서 정렬 혹은 쿼리가 수행되는 경우 성능을 최적화하기 위해 모든 하위 집합을 고려하는 많은 인덱스가 발생할 수 있으나 이것은 오히려 성능을 저하시킬 수 있음
// ***************** Before patterning
{
title: "Star Wars",
director: "George Lucas",
...
release_US: ISODate("1977-05-20T01:00:00+01:00"),
release_France: ISODate("1977-10-19T01:00:00+01:00"),
release_Italy: ISODate("1977-10-20T01:00:00+01:00"),
release_UK: ISODate("1977-12-27T01:00:00+01:00"),
...
},
// ***************** Attribute Pattern
{
title: "Star Wars",
director: "George Lucas",
...
releases: [
{
location: "USA",
date: ISODate("1977-05-20T01:00:00+01:00")
},
{
location: "France",
date: ISODate("1977-10-19T01:00:00+01:00")
},
{
location: "Italy",
date: ISODate("1977-10-20T01:00:00+01:00")
},
{
location: "UK",
date: ISODate("1977-12-27T01:00:00+01:00")
},
...
],
...
}
// Indexing may be like...
{ "releases.location": 1, "releases.date": 1}
The Bucket Pattern
- 사물 인터넷(IoT), 실시간 분석 또는 일반적으로 시계열 데이터와 작업할 때 효과적
- 데이터를 함께 묶음으로써 특정 데이터 그룹을 조직하는 것이 더 쉬워짐
// Data Example
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:00:00.000Z"),
temperature: 40
},
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:01:00.000Z"),
temperature: 40
},
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:02:00.000Z"),
temperature: 41
}
/// Wind Up
{
sensor_id: 12345,
start_date: ISODate("2019-01-31T10:00:00.000Z"),
end_date: ISODate("2019-01-31T10:59:59.000Z"),
measurements: [
{
timestamp: ISODate("2019-01-31T10:00:00.000Z"),
temperature: 40
},
{
timestamp: ISODate("2019-01-31T10:01:00.000Z"),
temperature: 40
},
...
{
timestamp: ISODate("2019-01-31T10:42:00.000Z"),
temperature: 42
}
],
transation_count: 42,
sum_temperature: 2413
}
The Outlier Pattern
- 일반 패턴과 다른 데이터가 있는 경우
// 일반적인 패턴
{
"_id": ObjetId("507f1f77bcf86cd79943901"),
"title": "A Genealogical Record of a Line of Alger",
"author": "Ken W. Alger",
...,
"customers_purchased": ["user00", "user01", "user02"]
}
// costomers_purchased의 리밋이 setting 값을 넘어선 경우
{
"_id": ObjetId("507f1f77bcf86cd79943901"),
"title": "A Genealogical Record of a Line of Alger",
"author": "Ken W. Alger",
...,
"customers_purchased": ["user00", "user01", "user02", ..., "user999"],
"has_extras": "true"
}
The Computed Pattern
- 애플리케이션에서 반복적으로 계산해야 하는 데이터가 있는 경우에 활용(매 시간 1,000,000 번의 읽기 && 1,000번의 쓰기)
The Subset Pattern
- 작업 세트의 데이터와 인덱스가 할당된 물리적 RAM을 넘어설 때 성능 저하 발생, 디스크 액세스가 발생하고 데이터가 RAM에서 밀려남
- Option1: 서버에 더 많은 RAM을 추가 -> 한계 존재
- Option2: 컬렉션을 샤드로 분할 -> 준비되지 않은 추가 비용과 복잡성 수반
- Option3: 작업 세트의 크기를 줄이는 것 : Subset Pattern
++ Example ++
[ Product Collection ]
- Only keep the ten most reent reviews
[ Review Collection ]
- Additional Information(Reviews)
- can be accessed if the user wants to see additional reviews
The Extended Reference Pattern
- 자주 엑세스되는 데이터를 모으기 위해 많은 Join 연산이 필요한 경우
++ Example ++
- 전자 상거래 애플리케이션에서 주문, 고객, 재고는 별개의 논리적 엔터티
- 특정 주문에 대한 정보를 모아야 하는 경우 문제가 발생할 수 있음 -> 한 고객이 N개의 주문을 가질 수 있어 1-N 관계 성립
- JOIN 연산을 줄이기 위해 각 주문에 대한 모든 고객 정보를 중복으로 포함하는 것은 많은 중복 정보를 초래할 수 있음
- 고객에 대한 모든 정보를 저장하는 대신 자주 액세스하는 필드만 복사
The Approximation Pattern
- 정확한 값이 아니라 '충분한' 데이터가 허용이 될 때 ex) 정확한 주민수 보다 약 39,000 명 정도로 충분할 때
- 데이터베이스의 인구를 모든 변경 사항마다 업데이트하는 대신 카운터를 구현하여 100번마다 1%의 확률로 업데이트 -> 쓰기작업 99% 감소
The Tree Pattern
- 데이터를 결합해야 하는 경우가 계층적일 때 (EX: 직원부터 CEO 까지의 보고 체인 식별)
- 부모 노드, 자식 노드를 나열하는 경우는 흔한 방ㅂ버이지만 여러 번의 액세스가 필요할 수 있음
- 대안으로 노드에서 계층 구조의 상위로 이르는 전체 경로 저장 가능
- 데이터의 중복이 발생하고, 정보가 상대적으로 불변인 경우 관리가 쉬우나 기업 구조와 같이 상황이 재조정될 수 있는 경우 필요에 따라 계층을 업데이트 해야하지만 그럼에도 항상 트리를 계산하는 것보다 적은 비용임
The Pre-Allocation Pattern
- 구조가 알려진 경우 구조를 채우거나 확장 가능성이 디자인을 훨씬 간단하게 만들 수 있음
- 나중에 채울 초기 빈 구조를 생성하도록 지시
The Document Versioning Pattern
- 일부 문서의 이전 버전을 유지하고 싶을 때
- 각 문서에 문서 버전을 추적할 수 있게 해주는 필드를 추가
[ 데이터 액세스 패턴의 가정 ]
- 각 문서에는 너무 많은 리비전이 존재하지 않는다.
- 버전을 생성해야 하는 문서가 너무 많지 않다.
- 대부분의 쿼리가 문서의 가장 최신 버전에서 수행된다.
'DEVELOPMENT > DB' 카테고리의 다른 글
[MongoDB] Sharding (0) | 2023.10.28 |
---|---|
[MongoDB] Configuration File Options (0) | 2023.10.28 |
[MongoDB] MongoDB Node.js Developer Path (0) | 2023.09.28 |
[MongoDB] Introduction to MongoDB (0) | 2023.09.13 |