MongoDB Glossary
MongoDB のコアコンセプトと用語リファレンス。
RDBMS vs MongoDB
flowchart LR
subgraph RDBMS
subgraph SQL_Database[SQL Database]
subgraph Tables
subgraph Rows
subgraph Columns
end
end
end
end
end
subgraph MongoDB
subgraph NoSQL_Database[NoSQL Database]
subgraph Collection
subgraph Documents
subgraph Fields
end
end
end
end
end
Tables <-->|vs| Collection
Rows <-->|vs| Documents
Columns <-->|vs| Fields
| RDBMS | MongoDB |
|---|---|
| Database | Database |
| Table | Collection |
| Row | Document |
| Column | Field |
| Index | Index |
| JOIN | $lookup / Embedded Document |
Schema Design Patterns
コア原則: 一緒にアクセスされるデータは一緒に保存すべき(Data that is accessed together should be stored together)
Inheritance Pattern
異なるタイプだが共通の属性を持つデータを同じ Collection に保存し、product_type フィールドで区別:
classDiagram
class Books {
title
author
publisher
}
class eBook {
title
author
publisher
product_type: "ebook"
}
class printedBook {
title
author
publisher
product_type: "printed"
}
class audioBook {
title
author
publisher
product_type: "audio"
}
Books <|-- eBook
Books <|-- printedBook
Books <|-- audioBook
その他の一般的な Pattern
| Pattern | 説明 | 適用シーン |
|---|---|---|
| Computed Pattern | 結果を事前計算して保存 | 頻繁に読み取られる集計結果 |
| Approximation Pattern | 正確な値ではなく近似値を保存 | カウンター、統計データ |
| Extended Reference Pattern | よく使うフィールドのコピーを埋め込み | $lookup クエリの削減 |
| Schema Versioning Pattern | ドキュメントに schema バージョンを含める | 段階的な schema 進化 |
Document Design 実例:ゲームキャラクターシステム
RPG ゲームのキャラクターシステムを通じて、RDBMS と MongoDB の設計の違いを比較します。
RDBMS 正規化設計
erDiagram
players ||--o{ characters : has
characters ||--o{ inventory : has
inventory }o--|| items : references
characters ||--o{ character_skills : has
character_skills }o--|| skills : references
players {
int player_id PK
string username
string email
datetime created_at
}
characters {
int character_id PK
int player_id FK
string name
string class
int level
int hp
int mp
}
items {
int item_id PK
string name
string type
int base_damage
}
inventory {
int inventory_id PK
int character_id FK
int item_id FK
int quantity
}
skills {
int skill_id PK
string name
int mana_cost
}
character_skills {
int character_id FK
int skill_id FK
int skill_level
}
特徴:
- 6 つのテーブル、Foreign Key で関連付け
- キャラクターの完全な情報を取得するには複数の JOIN が必要
- item の基本データの変更は 1 箇所の更新で OK
MongoDB ドキュメント設計
{
"_id": ObjectId("..."),
"username": "player123",
"email": "player@example.com",
"created_at": ISODate("2024-01-15"),
"characters": [
{
"character_id": "char_001",
"name": "DragonSlayer",
"class": "Warrior",
"level": 42,
"stats": {
"hp": 1500,
"mp": 200,
"strength": 85,
"agility": 45
},
"inventory": [
{
"item_id": "sword_001",
"name": "Flame Sword",
"type": "weapon",
"damage": 150,
"quantity": 1,
"equipped": true
},
{
"item_id": "potion_001",
"name": "Health Potion",
"type": "consumable",
"effect": "+500 HP",
"quantity": 10
}
],
"skills": [
{
"skill_id": "skill_001",
"name": "Flame Strike",
"level": 5,
"mana_cost": 50
}
]
}
]
}特徴:
- 1 つの Document に全ての関連データを含む
- キャラクターの完全な情報の取得は 1 回の読み取りのみ
- 「読み取り時に完全なデータが必要」なシーンに適している
設計比較
| 観点 | RDBMS | MongoDB |
|---|---|---|
| データ構造 | 複数テーブル + Foreign Key | 単一 Document 埋め込み |
| 完全なキャラクター取得 | 複数 JOIN | 1 回の読み取り |
| アイテム基本データ更新 | 1 箇所の更新で OK | 埋め込まれた全てのコピーを更新 |
| フィールド追加 | ALTER TABLE が必要 | 直接追加、schema 変更不要 |
| トランザクション一貫性 | ネイティブ ACID | 単一ドキュメント原子性、複数ドキュメントはトランザクション必要 |
| 適用シーン | データ関連が複雑、頻繁な更新が必要 | 読み取り中心、データが一緒にアクセスされる |
設計決定ガイド
埋め込み(Embedding)を使うべき場合:
- データが通常一緒に読み取られる
- 子データのライフサイクルが親データに依存
- 子データの数が限られており、無限に増えない
参照(Reference)を使うべき場合:
- 子データが親データから独立して存在
- 子データの数が大きくなる可能性がある
- 子データを独立してクエリする必要がある
Transaction
MongoDB はマルチドキュメント ACID トランザクションをサポート(4.0+)。
Read Concern
読み取り操作が返すデータの一貫性レベルを制御:
| Level | 説明 |
|---|---|
local | ローカルの最新データを返す(デフォルト) |
available | local に類似、sharded cluster 用 |
majority | 過半数のノードで確認されたデータを返す |
linearizable | すべての成功した書き込みを反映したデータを返す |
snapshot | トランザクション開始時のスナップショットを返す |
Write Concern
書き込み操作の確認レベルを制御:
| Level | 説明 |
|---|---|
w: 1 | プライマリノード確認(デフォルト) |
w: "majority" | 過半数ノード確認 |
w: <number> | 指定数のノード確認 |
j: true | journal 書き込み後に確認 |
Read Preference
どのノードからデータを読み取るかを制御:
| Mode | 説明 |
|---|---|
primary | プライマリノードからのみ読み取り(デフォルト) |
primaryPreferred | プライマリ優先、利用不可の場合セカンダリから読み取り |
secondary | セカンダリノードからのみ読み取り |
secondaryPreferred | セカンダリ優先 |
nearest | ネットワーク遅延が最も低いノードから読み取り |
Replica Set
MongoDB の高可用性機構、複数の mongod インスタンスで構成。
ノードタイプ
| タイプ | 説明 |
|---|---|
| Primary | すべての書き込み操作を受け付ける |
| Secondary | Primary のデータをレプリケート、読み取り処理可能 |
| Arbiter | 投票のみ参加、データを保存しない |
Explain(実行計画分析)
SQL データベースの実行計画分析については、SQL Explain を参照してください。
explain() を使用してクエリパフォーマンスを分析:
db.collection.find({ ... }).explain("executionStats")queryPlanner フィールド説明
| フィールド | 説明 |
|---|---|
namespace | クエリ対象のコレクション |
indexFilterSet | インデックスを使用したか |
parsedQuery | パース後のクエリ条件 |
winningPlan | 最適な実行計画 |
rejectedPlans | 却下された実行計画 |
executionStats フィールド説明
| フィールド | 説明 |
|---|---|
executionSuccess | 実行成功したか |
nReturned | 返されたドキュメント数 |
executionTimeMillis | 実行時間(ミリ秒) |
totalKeysExamined | インデックススキャン回数 |
totalDocsExamined | ドキュメントスキャン回数 |
Stage タイプ
| Stage | 説明 | パフォーマンス |
|---|---|---|
COLLSCAN | フルテーブルスキャン | ⚠️ 避けるべき |
IXSCAN | インデックススキャン | ✅ 推奨 |
FETCH | インデックスに基づいてドキュメントを取得 | ✅ 正常 |
IDHACK | _id クエリの最適化 | ✅ 最適 |
SORT | メモリ内ソート | ⚠️ インデックス追加を検討 |
LIMIT | 返却数を制限 | ✅ 正常 |
SKIP | ドキュメントをスキップ | ⚠️ 大量 skip はパフォーマンス低下 |
SHARD_MERGE | シャード結果をマージ | ✅ 正常 |
COUNT_SCAN | インデックスを使用してカウント | ✅ 推奨 |
COUNTSCAN | インデックスを使用せずカウント | ⚠️ 避けるべき |
TEXT | 全文インデックスクエリ | ✅ 正常 |
PROJECTION | フィールド射影 | ✅ 正常 |
避けるべき Stage
以下の Stage が出現した場合は最適化を検討:
- COLLSCAN - フルテーブルスキャン、インデックスを作成すべき
- SORT - メモリ内ソート、複合インデックスを作成すべき
- SUBPLA - インデックスを使用しない
$orクエリ - COUNTSCAN - インデックスを使用しない count
- 大量の SKIP - range query での代替を検討
Explain 出力例
{
"explainVersion": "1",
"stages": [
{
"$cursor": {
"queryPlanner": {
"namespace": "demo.sop",
"parsedQuery": { "_id": { "$eq": "951753" } },
"winningPlan": { "stage": "IDHACK" }
},
"executionStats": {
"executionSuccess": true,
"nReturned": 1,
"executionTimeMillis": 0,
"totalKeysExamined": 1,
"totalDocsExamined": 1
}
}
},
{
"$lookup": {
"from": "sop_acl",
"as": "acl_data",
"localField": "_id",
"foreignField": "sop_id",
"totalDocsExamined": 4,
"collectionScans": 1,
"indexesUsed": []
}
}
]
}上記の例で $lookup ステージの collectionScans: 1 は sop_acl に対してフルテーブルスキャンが行われたことを示しており、sop_id フィールドにインデックスを作成することを検討すべきです。
Aggregation Pipeline
アグリゲーションパイプラインは MongoDB のデータ分析のコア機能で、SQL の GROUP BY に類似。
よく使うステージ
詳細は MongoDB CLI - Aggregation Pipeline を参照
MongoDB Compass
MongoDB 公式の GUI ツール、以下を提供:
- 視覚的なクエリビルダー
- Schema 分析
- パフォーマンス監視
- インデックス管理
- Aggregation Pipeline ビルダー