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
RDBMSMongoDB
DatabaseDatabase
TableCollection
RowDocument
ColumnField
IndexIndex
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 ゲームのキャラクターcharacterシステムを通じて、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 かいりのみ
  • 完全かんぜんなデータが必要ひつよう」なシーンにてきしている

設計比較

観点かんてんRDBMSMongoDB
データ構造こうぞう複数ふくすうテーブル + Foreign Key単一たんいつ Document
完全かんぜんなキャラクター取得しゅとく複数ふくすう JOIN1 かい
アイテム基本きほんデータ更新こうしん1 箇所かしょ更新こうしんで OKまれたすべてのコピーを更新こうしん
フィールド追加ついかALTER TABLE が必要ひつよう直接ちょくせつ追加ついか、schema 変更へんこう不要ふよう
トランザクション一貫性いっかんせいネイティブ ACID単一たんいつドキュメント原子性げんしせい複数ふくすうドキュメントはトランザクション必要ひつよう
適用てきようシーンデータ関連かんれん複雑ふくざつ頻繁ひんぱん更新こうしん必要ひつよう中心ちゅうしん、データが一緒いっしょにアクセスされる

設計決定ガイド

み(Embedding)を使つかうべき場合ばあい

  • データが通常つうじょう一緒いっしょられる
  • データのライフサイクルがおやデータに依存いぞん
  • データのかずかぎられており、無限むげんえない

参照さんしょう(Reference)を使つかうべき場合ばあい

  • データがおやデータから独立どくりつして存在そんざい
  • データのかずおおきくなる可能性かのうせいがある
  • データを独立どくりつしてクエリする必要ひつようがある

Transaction

MongoDB はマルチドキュメント ACID トランザクションをサポート(4.0+)。

Read Concern

読み取り操作が返すデータの一貫性レベルを制御:

Level説明
localローカルの最新データを返す(デフォルト)
availablelocal に類似、sharded cluster 用
majority過半数のノードで確認されたデータを返す
linearizableすべての成功した書き込みを反映したデータを返す
snapshotトランザクション開始時のスナップショットを返す

Write Concern

書き込み操作の確認レベルを制御:

Level説明
w: 1プライマリノード確認(デフォルト)
w: "majority"過半数ノード確認
w: <number>指定数のノード確認
j: truejournal 書き込み後に確認

Read Preference

どのノードからデータを読み取るかを制御:

Mode説明
primaryプライマリノードからのみ読み取り(デフォルト)
primaryPreferredプライマリ優先、利用不可の場合セカンダリから読み取り
secondaryセカンダリノードからのみ読み取り
secondaryPreferredセカンダリ優先
nearestネットワーク遅延が最も低いノードから読み取り

Replica Set

MongoDB の高可用性機構、複数の mongod インスタンスで構成。

ノードタイプ

タイプ説明
Primaryすべての書き込み操作を受け付ける
SecondaryPrimary のデータをレプリケート、読み取り処理可能
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 が出現した場合は最適化を検討:

  1. COLLSCAN - フルテーブルスキャン、インデックスを作成すべき
  2. SORT - メモリ内ソート、複合インデックスを作成すべき
  3. SUBPLA - インデックスを使用しない $or クエリ
  4. COUNTSCAN - インデックスを使用しない count
  5. 大量の 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: 1sop_acl に対してフルテーブルスキャンが行われたことを示しており、sop_id フィールドにインデックスを作成することを検討すべきです。


Aggregation Pipeline

アグリゲーションパイプラインは MongoDB のデータ分析のコア機能で、SQL の GROUP BY に類似。

よく使うステージ

詳細は MongoDB CLI - Aggregation Pipeline を参照


MongoDB Compass

MongoDB 公式の GUI ツール、以下を提供:

  • 視覚的なクエリビルダー
  • Schema 分析
  • パフォーマンス監視
  • インデックス管理
  • Aggregation Pipeline ビルダー

関連トピック