本日、適当な方法で1対多の実装方法を検討しました。
ググるとMongoDB Blogにスキーマ設計が6パターン示されていました。ちょっと以下に転写しつつ要約します。自己メモとして。
6 Rules of Thumb for MongoDB Schema Design: Part 1
6 Rules of Thumb for MongoDB Schema Design: Part 2
6 Rules of Thumb for MongoDB Schema Design: Part 3
1 対 少々(embedding)
1 対 多(child-referencing)
- Parts
- Products
- 検索(application-level joinっていうらしい)
1 対 めちゃ多(parent-referencing)
- hosts, logmsg(1ドキュメントのサイズ上限が16MBなのでhost情報を参照型?にするとlogmsgドキュメントのサイズを小さくできることができる、という効果があるとか、ふんふん。)
- 検索方法
双方向参照(two-way referencing)
- Person->Task, Task->Personの両方から参照することができるようにする。
多対1での非正規化(Denormalizing from Many -> One)
- これは非正規化前
- そしてこれが非正規化した後(tasksの中にキー以外に使いたいtask情報を入れておくことでapplication-level joinを避けることができる)
- 検索
1対多での非正規化(Denormalizing from One -> Many)
- Partsの中にProductsの情報を埋め込んでapplication-level joinを避ける
1 対 めちゃ多の非正規化(Denormalizing With “One-To-Squillions” Relationships)
- 非正規化の方法としては1側にあるいは多側に情報を含める方法がある。例えば、多側であるlogmsgに正規化状態では不要だったipaddrを入れてみる。
- すると、以下のようにipaddrで最新のログを1つのクエリーで取得することができちゃう。
- 多側に格納しておきたい情報が少ないなら以下のように情報を埋め込んでしまい参照をやめちゃう手があるよ。
(疲れたので途中で終了)
でも、だいたいわかった気がする。追加や更新が多い場合とかもデザインパターンがありそうだなぁ。