参照の基本概念
MongoDBはドキュメント指向データベースですが、リレーショナルデータベースのような関係性を表現するために、ドキュメント間で参照を持つことができます。主な参照パターンとして「親から子への参照」と「子から親への参照」があります。
1. 親から子への参照(Parent References Children)
親ドキュメントが子ドキュメントのIDを配列として保持するパターンです。
構造例
親ドキュメント(authors)
{
_id: ObjectId("..."),
name: "山田太郎",
books: [
ObjectId("book1"),
ObjectId("book2"),
ObjectId("book3")
]
}
子ドキュメント(books)
{
_id: ObjectId("book1"),
title: "MongoDBの基礎",
year: 2023
}
メリット
- 親から子のリストを直接取得できる
- 親ドキュメントを見るだけで、関連する子の数や存在を把握できる
- 子が少数の場合、管理が簡単
デメリット
- 子の数が増えると親ドキュメントのサイズが肥大化する(16MBの制限に注意)
- 子を追加・削除するたびに親ドキュメントの更新が必要
- 大量の子を持つ場合、パフォーマンスが低下する
適用シーン
- 子の数が限定的(数十〜数百程度)
- 親から子の一覧を頻繁に取得する
- 例:ユーザーと投稿、カテゴリと商品
2. 子から親への参照(Child References Parent)
子ドキュメントが親ドキュメントのIDを保持するパターンです。
構造例
親ドキュメント(authors)
{
_id: ObjectId("author1"),
name: "山田太郎"
}
子ドキュメント(books)
{
_id: ObjectId("..."),
title: "MongoDBの基礎",
year: 2023,
author_id: ObjectId("author1")
}
メリット
- 親ドキュメントのサイズが一定に保たれる
- 子の数が無制限に増やせる
- 子の追加・削除が親に影響しない
- インデックスを作成すれば効率的にクエリできる
デメリット
- 親から子を取得する際に別途クエリが必要
- 集約や結合処理が必要になる場合がある
適用シーン
- 子の数が多い、または無制限に増える可能性がある
- 子から親を参照する頻度が高い
- 例:ブログ記事とコメント、注文と注文明細
使い分けの判断基準
親から子への参照を選択する場合
- 子の数が制限的(通常100以下)
- 親と子を同時に取得することが多い
- 子のリストを頻繁に表示する
子から親への参照を選択する場合
- 子の数が多い、または予測できない
- 子を個別に扱うことが多い
- スケーラビリティが重要
両方向参照
場合によっては、両方向から参照を持つこともあります。これはクエリのパフォーマンスを最適化したい場合に有効ですが、データの一貫性を保つための管理が複雑になります。
// 親
{
_id: ObjectId("author1"),
name: "山田太郎",
books: [ObjectId("book1"), ObjectId("book2")]
}
// 子
{
_id: ObjectId("book1"),
title: "MongoDBの基礎",
author_id: ObjectId("author1")
}
まとめ
参照パターンの選択は、データの性質とアクセスパターンによって決まります。一般的には、子から親への参照の方がスケーラブルで柔軟性が高いため、多くの場合に推奨されます。ただし、具体的な要件に応じて最適なパターンを選択することが重要です。