次のDB構造がある
とします。アプリケーションは、すべての詳細(モデル、製品ファミリー、ブランド、プロデューサー)を含む記事のリストを表示する必要があります。そのためには、必要なデータを取得するために、より多くのJOINを作成する必要があります。
次のようにArticleテーブルに冗長FKを作成して、アプリケーションのパフォーマンスを向上させても大丈夫ですか?それは実際にパフォーマンスを向上させますか?
次のDB構造がある
とします。アプリケーションは、すべての詳細(モデル、製品ファミリー、ブランド、プロデューサー)を含む記事のリストを表示する必要があります。そのためには、必要なデータを取得するために、より多くのJOINを作成する必要があります。
次のようにArticleテーブルに冗長FKを作成して、アプリケーションのパフォーマンスを向上させても大丈夫ですか?それは実際にパフォーマンスを向上させますか?
はい、階層内の「中間」オブジェクトのデータを取得したくない場合は、その方法でパフォーマンスを向上させることができます。これは非正規化の一般的な形式です。矛盾が入り込まないように注意する必要があることに注意してください。
私は通常、非正規化されたデータを検証し、エラーをメールで送信して自動的に修正する夜間タスクを設定します。これは難しくなく、厄介な種類のバグを排除します。
人々がそうする別の理由は、すべてのテーブルを同じキーで分割することです。
設計によってパフォーマンスが向上するかどうかを確認する最善の方法は、実際に試してみることです。2 番目に優れた方法は、実行する必要がある可能性が高いクエリを熟考し、それらを頭の中でモデル化することです。実行するクエリやデータベースのサイズがわからないと、パフォーマンスが向上するかどうかを判断するのは困難です。
非常に大まかに言えば、非常に大きなデータベースを使用しない限り、パフォーマンスに測定可能な影響は見られないと思います (適切なハードウェアでこれを実行し、インデックスを調整したと仮定します)。「非常に大きい」とは、いくつかのテーブルに数百万行あると考えています。
本当に非正規化する必要がある場合は、冗長なキーで通常の設計を「汚染」するのではなく、明示的に非正規化されたテーブルを作成することをお勧めします。「あるべき姿」と「妥協点」を別々に考慮した設計は、2 つを混ぜ合わせるよりもはるかに簡単に理解できます。
それを実現するには、別のテーブルを作成します-おそらく「cached_articles」で、次の列があります。
article_id
...(article data)
model_id
....(model data)
family_id
...(family data)
brand_id
....(brand data)
producer_id
....(producer data)
このテーブルは、バッチ ジョブまたはトリガーによって維持できます。アプリケーション コードは、正規化されたテーブルにのみ書き込み、必要な場合にのみキャッシュ テーブルから読み取る必要があります。
また、堅牢な「整合性チェック」メカニズムを構築して、アプリケーションの破損の原因となる可能性のあるデータの問題を特定する必要があります。データベースがこの種の設計が必要になるサイズに成長すると、これらの一貫性チェックは大きな問題になります。同じパフォーマンスの問題が発生するためです...