データベースの非正規化。 なんで? いつ? どうやって?

非正規化は悪ですか、それとも調理できるようにするだけでよいのでしょうか?



非正規化は、曲がった手の結果ではありません。 これは未完成の正規化ではなく、生産性を高めるための通常の形式の意図的な違反です。

非正規化の問題は複数回発生しました。 正常な形の原則に違反して、良心と取引をしなければならないたびに、不満感、私たちの無能に対する誤った認識がありました。 時間が経つにつれて、チームで作業するとき、これは私の問題だけではないことが判明しました。 それを理解する時ですか?非正規化は悪ですか、それとも単に調理する必要があるだけですか?



理解したかったこと






非正規化はいつ必要ですか? サインと匂い。


非正規化が役立つ可能性のある一般的な状況を検討してください。



多数のテーブルが結合します。


完全に正規化されたデータベースへのクエリでは、多くの場合、1ダースまたはそれ以上のテーブルを結合する必要があります。 また、各接続は非常にリソースを消費する操作です。 その結果、そのような要求はサーバーリソースを消費し、実行が遅くなります。

この状況では、次のことに役立ちます。





推定値。
多くの場合、クエリはゆっくり実行され、多くのリソースを消費します。特にグループ化や集計関数(Sum、Maxなど)を使用する場合は、いくつかの複雑な計算が実行されます。 頻繁に使用される(計算が困難な)計算データを含む列を表1-2に追加することが理にかなっている場合があります。

各注文の合計値を決定するとします。 これを行うには、最初に各製品のコストを決定する必要があります(「製品単位数」*「製品単位価格」-割引)。 その後、注文のコストをグループ化する必要があります。

このリクエストの実行は非常に複雑であり、データベースに多数の注文に関する情報が含まれている場合、多くの時間がかかる可能性があります。 そのようなリクエストを実行する代わりに、注文の段階で、その値を決定し、注文テーブルの別の列に保存できます。 この場合、目的の結果を得るには、この列から以前に計算された値を抽出するだけで十分です。

事前に計算された値を含む列を作成すると、クエリの実行時に大幅に時間を節約できますが、この列のタイムリーなデータ変更が必要です。



長いフィールド。
データベースに長いフィールド(Blob、Longなど)を含む大きなテーブルがある場合、別のテーブルの長いフィールドを取り出すと、そのようなテーブルへのクエリの実行を大幅にスピードアップできます。 たとえば、写真自体のカタログ(プロ品質、高解像度、適切なサイズ)をブロブフィールドに保存するなど、データベースに作成する必要があります。 正規化の観点から見ると、次のテーブル構造は完全に正しいものになります。

写真付き身分証明書

著者ID

カメラモデルID

写真自体(ブロブフィールド)。

ここで、クエリがどのくらいの期間機能するかを想像してください。作成者が撮影した写真の数をカウントします...

この状況での正しい判断(正規化の原則に違反しますが)は、写真IDと写真自体のblobフィールドの2つのフィールドのみで構成される別のテーブルを作成することです。 次に、メインテーブル(今は巨大なblobフィールドがない)からのサンプルがすぐに移動しますが、写真自体を見たい場合は-待ってください...



非正規化が正当化されるタイミングを判断する方法は?




コストとメリット。


これらのステップまたは他のステップを正当化する方法を決定する1つの方法は、コストと考えられる利点の観点から分析を行うことです。 非正規化データモデルの費用はいくらですか?

要件(達成したいもの)を定義する->データ要件(観察する必要があるもの)を決定する->これらの要件を満たす最小ステップを見つける->実装コストを計算する->実装する

コストには、ディスクスペース、この構造の管理に必要なリソース、このプロセスのサービスに関連する時間遅延による機能の損失などの物理的側面が含まれます。 非正規化を支払う必要があります。 非正規化されたデータベースでは、データの冗長性が向上し、パフォーマンスは向上しますが、関連するデータを制御するためにより多くの労力が必要になります。 データが繰り返され、追跡がより困難になるため、アプリケーションの作成プロセスはより複雑になります。 さらに、参照整合性の実装は簡単なタスクではありません。関連するデータは異なるテーブルに分割されます。

利点には、要求を実行するときのパフォーマンスの向上と、より高速な応答を取得する機能が含まれます。 さらに、スループット、顧客満足度、生産性の向上、外部開発者によるツールのより効率的な使用など、他の利点も得られます。



要求頻度とパフォーマンスの安定性。


たとえば、企業が毎日生成する1000件のクエリの70%は、詳細データではなく要約レベルのクエリです。 サマリーテーブルを使用すると、クエリは4分ではなく約6秒で完了します。 処理時間は2730分短くなります。 サマリーテーブルのサポートに毎週費やす必要がある105分間に調整しても、週に2625分節約できます。これにより、サマリーテーブルの作成が完全に正当化されます。 時間が経つにつれて、クエリのほとんどが要約データではなく詳細データに対処されることがあります。 サマリーテーブルを使用するクエリの数が少ないほど、他のプロセスに影響を与えずに簡単に破棄できます。



その他


最適化の次のステップを実行するかどうかを決定する際に考慮する必要があるのは、上記の基準だけではありません。 ビジネスの優先順位やエンドユーザーのニーズなど、他の要因を考慮する必要があります。 ユーザーは、技術的な観点から、すべての要求を数秒で完了することを望むユーザーの要件によってシステムアーキテクチャがどのように影響を受けるかを理解する必要があります。 この理解を実現する最も簡単な方法は、そのようなテーブルの作成と管理に関連するコストを概説することです。



非正規化を正しく実装する方法。




詳細なテーブルを保存する


ビジネスにとって重要なデータベースの機能を制限しないために、置換ではなく共存戦略を順守する必要があります。 非正規化された構造を追加して、詳細な分析のために詳細なテーブルを保存します。 たとえば、ヒットカウンター。 ビジネスでは、Webページへのアクセス数を知る必要があります。 ただし、分析には(期間ごと、国ごとなど)詳細なデータ(訪問ごとの情報を含む表)が必要になる可能性が非常に高くなります。



トリガーを使用する


データベーストリガーを使用して情報の整合性(重複データのID)を維持する場合は、データベース構造を非正規化しても、正規化を引き続き利用できます。

たとえば、計算フィールドが依存する各列に計算フィールドを追加する場合、必要なデータを計算フィールドに書き込む単一のストアドプロシージャ (これは重要です!)を呼び出すトリガーがハングします。 計算フィールドが依存する列を逃さないようにするだけです。



ソフトウェアサポート


Naroimer、MySQLバージョン4.1にはトリガーとストアドプロシージャはまったくありません。 したがって、アプリケーション開発者は、非正規化されたデータベースでデータの一貫性を確保するように注意する必要があります。 トリガーと同様に、変更されるフィールドに応じてすべてのフィールドを更新する1つの関数が必要です。



まとめ


まとめると。 非正規化では、データベースの速度を上げることとデータの競合のリスクを増やすこと、Selectを書くプログラマーの生活を楽にすること、データベースのデータを入力して更新する人のタスクを複雑にすることのバランスを保つことが重要です。 したがって、ベースを非正規化する必要があるのは、それなしではできない場合にのみ、非常に慎重に、非常に選択的にベースを非正規化することです。

事前に非正規化の長所と短所を計算することが不可能な場合、最初に正規化されたテーブルを使用してモデルを実装し、問題のあるクエリを最適化するために非正規化する必要があります。



All Articles