非正規化

コラム 10.5

翻訳の進捗

本章で学ぶこと:

  • 非正規化とは何かを理解します
  • 従来のリレーショナルデータベースとMongoDBの比較
  • あなたのデータを非正規化するべきでは*ない*ときを学ぶ
  • データを非正規化するとは、「通常」の形式でそのデータを格納しないことを意味します。 言い換えれば、非正規化は、ぶら下がった同じデータの複数のコピーを有することを意味します。

    前の章では、我々はすべてのコメントを時間かけてロードすることを避けるために、 postオブジェクトにコメントの数を非正規化しました。 データモデリングの意味では、その値を把握するために、 いつでもコメントの正しい組み合わせを数えることができるようにするには、冗長です。 (パフォーマンスの考慮を除外しています)

    非正規化は、多くの場合、開発者のための余分な作業を意味します。 この例では、我々はコメントを追加または削除するたびに、 commentsCountフィールドが正確のままだと保証するために、関連する投稿を更新した事を覚えておく必要があります。 これはまさに、MySQL等のリレーショナルデータベースはしかめ面になるアプローチです。

    しかし、通常のアプローチは、欠点があります。: commentsCountプロパティなしで、私たちが最初に何をしていたか思い出してください。 コメントを数えることができるように、毎回、紐付いているすべてのコメントを送信する必要がでてきます。 非正規化は、完全にこれを避けることができます。

    特別なパブリケーション

    私たちは、興味を持っているコメント数を取得し特殊なパブリケーションを作成することも可能でしょう。 (例えば、現在、サーバー上に集約クエリを経由して、見ることができる投稿のコメントカウント)

    しかし、それはこのようなパブリケーションコードの複雑さが、 非正規化によって作成された困難を上回るならば検討する価値があります..

    もちろん、このような考察は、アプリケーション事に異なります。: もし、データの整合性が最重要なコードを記述している場合、パフォーマンスの向上より、 データの不整合を回避することがはるかに重要かつ優先順位の高いです。

    ドキュメントに埋め込むべき vs 複数のコレクションを使う

    もしMongoDBの経験がある方ならば場合は、 コメント用に第二のコレクションを作成したことを見て驚いたかもしれません: なぜ投稿ドキュメント内のリスト内へコメントを埋め込まなかったのでしょう?

    これは、コレクションレベルで動作しているときのMeteorツールの多くは、 たくさんの良い仕事が得られることが判明したのです。たとえば:

    1. カーソルを反復処理(collection.find()の結果に対して)するとき{{#each}}ヘルパーは非常に効率的でした。 それはより大きな文書内のオブジェクトの配列を反復処理するときは同じことが当てはまりません。
    2. allowdenyの操作はドキュメントレベルの方が容易です。 個別のコメントの変更が正しいことを保証するのをpostレベルで操作するのはより複雑です。
    3. DDPは、文書の最上位の属性のレベルで動作します。–それの意味するところは、 commentspostのプロパティであった場合、コメントがポストに作成されるたびに、 サーバーが接続されている各クライアントに、そのポストの全体の更新されたコメントの一覧を送信します。
    4. パブリケーションとサブスクリプションは、文書のレベルで制御することが非常に簡単です。 例えば、 ある投稿のコメントをページ分割したい場合、コメントが専用のコレクション無ければ、 実装が難しい事がわかるでしょう。

    Mongoは文書を取り出すための高価なクエリ数を削減するために文書に埋め込むことを提案します。 しかし、少なくともそれはMeteorのアーキテクチャではアカウントを取る場合くらいです。 ほとんどの時間は、基本的に自由であるクライアントサイドのデータベースアクセスでコメントを照会しているからです。

    非正規化のマイナス面

    あなたのデータを非正規化するべきではないと判断されるのは良い議論です。 非正規化に対する良いドキュメントとしてSarah MeiのWhy You Should Never Use MongoDB があります。