私たちは皆、データベースの正規化に精通していると思います。
私の質問は次のとおりです。テーブルを非正規化するときに使用するガイドラインは何ですか?
私たちは皆、データベースの正規化に精通していると思います。
私の質問は次のとおりです。テーブルを非正規化するときに使用するガイドラインは何ですか?
回答:
OLAP操作の場合は非正規化、OLTPの場合は正規化(非正規化セクションのリンク記事から)
通常、オンライントランザクション処理(OLTP)を対象としたデータベースは、オンライン分析処理(OLAP)を対象としたデータベースよりも正規化されています。OLTPアプリケーションは、スーパーマーケットのチェックアウトカウンターで販売記録を更新するなど、大量の小規模なトランザクションを特徴としています。各トランザクションがデータベースを一貫した状態のままにすることが期待されます。対照的に、OLAP操作用のデータベースは、主に「主に読み取り」データベースです。OLAPアプリケーションは、長期間にわたって蓄積された履歴データを抽出する傾向があります。このようなデータベースの場合、冗長または「非正規化された」データはビジネスインテリジェンスアプリケーションを促進する可能性があります。特に、スタースキーマのディメンションテーブルには、多くの場合、非正規化データが含まれています。非正規化データまたは冗長データは、抽出、変換、ロード(ETL)処理中に慎重に制御する必要があり、ユーザーはデータが一貫した状態になるまでデータの表示を許可しないでください。スタースキーマの正規化された代替は、スノーフレークスキーマです。多くの場合、コンピューターとRDBMSソフトウェアがより強力になるにつれて非正規化の必要性は減りましたが、ハードウェアとソフトウェアのパフォーマンスとともにデータ量が一般的に増加するため、OLAPデータベースは依然として非正規化スキーマを使用することがよくあります。
非正規化は、コンピューター化された金銭登録機やモバイルデバイスなどの小型コンピューターでのパフォーマンスを向上させるためにも使用されます。非正規化は、RDBMSがプラットフォーム(Palmなど)に存在しない場合、またはデータに変更を加えず、迅速な応答が重要な場合にも使用できます。
制御された非正規化を適用する潜在的に理にかなっている理由の1つは、そうでなければ不可能な整合性制約をデータに適用できる場合です。ほとんどのSQL DBMSでは、マルチテーブル制約のサポートが非常に制限されています。SQLで、特定の制約を実装する唯一の効果的な方法は、制約に関係する属性がすべて同じテーブルに存在することを保証することです-正規化によってそれらが別のテーブルに属することを要求される場合でも。
制御された非正規化とは、冗長データが原因で不整合が発生しないようにするメカニズムが実装されていることを意味します。非正規化を行う価値があるかどうかを判断する際には、これらの追加のコントロールのコストと一貫性のないデータのリスクを考慮する必要があります。
非正規化のもう1つの一般的な理由は、ストレージ構造の変更を許可するか、DBMSで許可されない他の物理的な最適化を許可することです。物理データの独立性の原則によれば、DBMSは、データベース内のデータの論理表現を不必要に変更することなく、内部ストレージ構造を構成する手段を備えている必要があります。残念ながら、多くのDBMSは、特定のデータベーススキーマで使用可能な物理的な実装オプションを非常に制限しています。それらは、目的の論理モデルの準最適な実装のみをサポートすることにより、物理データベースの独立性を損なう傾向があります。
それは明らかなはずですが、言う必要があります:すべての場合において、パフォーマンスを決定できるのは物理実装機能の変更のみです-内部データ構造、ファイル、インデックス付け、ハードウェアなどの機能。正規化と非正規化は、パフォーマンスまたはストレージの最適化とは関係ありません。
計算されたデータに頻繁にアクセスする場合は、この質問への回答で提案されているように非正規化します。計算されたデータを保存および保守するコストは、負荷プロファイルが読み取りが多い場合に何度も再計算するコストよりも少なくなります。
制約付きのデータ整合性を強制できるように、私は定期的に非正規化します。1つの例は、このサイトに関する最近の質問です。別のテーブルの列を複製し、CHECK制約を使用して別の列と比較できるようにします。この手法の別の例は、私のブログ投稿です。
CHECK制約から呼び出されるスカラーUDFでそのような機能をラップしない限り、CHECK制約を使用して異なる行または異なるテーブルの列を比較することはできません。実際にビジネスルールを実施するために異なる行または異なるテーブルの列を比較する必要がある場合はどうでしょうか?たとえば、医師の勤務時間を知っていて、すべての予定が勤務時間内に収まるようにしたいとしますか?もちろん、トリガーまたはストアドプロシージャを使用してこのビジネスルールを実装することはできますが、トリガーもストアドプロシージャも、すべてのデータがクリーンであることを100%保証することはできません。ダーティデータ、トリガーを再度有効化または再作成します。また、誰かがストアドプロシージャをバイパスしてテーブルを直接変更できます。
FKおよびCHECK制約のみを使用してこのビジネスルールを実装する方法を示します。これにより、すべての制約が信頼されている限り、すべてのデータがビジネスルールを満たすことが保証されます。
さらに別の例は、期間にギャップやオーバーラップがないことを強制する方法です。
Fulfillable
、各Fulfillable項目のすべての詳細を持つテーブルは、その後、そこにあるFulfillableQueue
実装テーブルSQL Serverのキューが。特定のFulfillablesのみStateID
がキューにある可能性があります。StateID
はFulfillable
テーブルにありますが、私はそれを複製しFulfillableQueue
、この制約をFOREIGN KEY
とCHECK
制約を強制します。