7

次の 2 つのテーブルを含む保険会社のデータベースを設計しているとします。

お客様

CustomerID, CustomerName

ポリシー

PolicyID, CustomerID, EffectiveDate, ExpirationDate

ポリシーの有効期限が今日以降であるようなポリシーを持っている場合、顧客は「アクティブ」と見なされます。当然のことながら、非アクティブな顧客を除外する、またはその逆のクエリを多数作成することを期待しています。Customers私の議論は、フィールド「アクティブ」をテーブル に追加するかどうかです。

一方では、これにより一連のクエリのパフォーマンスが向上し、見た目がすっきりして理解しやすくなります。

一方で、毎日更新する必要があります。また、顧客がアクティブであると見なされるかどうかは、完全にポリシー テーブル内のデータの関数です。したがって、「アクティブ」列を追加することで、顧客がアクティブとしてマークされているが、ポリシー データでは非アクティブと見なされる (またはその逆) という潜在的なシナリオを作成しています。つまり、データ自体が矛盾するようなデザインを作成しています。

これは悪い習慣ですか?

4

9 に答える 9

5

あなたが説明しているのは、非正規化データベース スキーマと呼ばれるものです。データの一貫性が保たれていることを確認できる限り、パフォーマンスを向上させるために使用するのは完全に有効な手法です。

さらに読む: https://en.wikipedia.org/wiki/Database_normalization

于 2013-06-24T20:39:41.603 に答える
2

まず、ポリシー テーブルに対する潜在的なクエリ高価であることに注意することから始めます (ただし、これはインデックスを適切に使用することで大幅に改善できます)。特定の顧客のすべてのポリシーを調べて、アクティブなポリシーがあるかどうかを判断する必要があります。

ただし、この質問に答えるのに十分な情報を提供していません。

ここに 2 つの異なるシナリオがあります。顧客は、毎日常にポリシーを追加、削除、および変更します。データベースの大部分は、データを最新の状態に保つという運用上の問題に専念しています。その場合、ほとんどのクエリはポリシー レベルになります。顧客が何らかの理由でアクティブかどうかについてレポートを作成する必要がある場合があります。この場合、「時折の」クエリのためにデータ構造を変更する価値はないようです。適切な焦点は、データが確実に更新されるようにすることです。

あるいは。データベースは毎晩ロードされ、主にアクティブな顧客に関するレポート目的で使用され、ポリシーの詳細ではありません(ポリシーに参加する必要がある場合は、何も保存されません)。中間更新はなく、ほとんどのクエリは顧客レベルを参照し、アクティブ フラグを使用します。さて、ここでは価値があるようです。

あなたの状況で私が抱えている課題は、トランザクション目的(高度に正規化された)とレポート(多くの場合、正規化されていない)の両方のためにデータベースを設計しているように見えることです。両者は必ずしもうまく混ざり合うとは限りません。これが簡単な理由です。5 分かかる興味深いレポート クエリを実行します。この 5 分間、1 つ以上のテーブルがクエリのためにロックされます。または、更新によって使用中のテーブルが定期的にロックされるため、クエリに 1 時間かかります。

制度の使い方をもっと考える必要があると思います。データ マート、特にラルフ キンボール (たとえば、彼のクラス「データ ウェアハウス ツールキット」) で説明されているディメンション マートについて学ぶことをお勧めします。「データマート」の概念が役立つかもしれません。

また、運用システムでもこのような情報を最新の状態に保つことができるトリガーについても学ぶ必要があります。また、列に直接格納されていない一般的な情報にアクセスする方法である計算列とビューについても説明します。

于 2013-06-24T21:11:05.630 に答える
1

私の経験では、フィールドを追加すると、将来のある時点で、他の誰かがそれらを同期させなくなる可能性が高くなります。私はデータ ウェアハウスで 5 年間働いていましたが、これは対処が難しい一般的な問題でした。
これに対処するには、次の 2 つのいずれかを行うことを検討します。

  • 2 つの日付フィールドを使用して計算を行う関数またはストアド プロシージャをデータベースに作成します。

また

  • 格納されたフィールドに基づいてアクティブを計算する、使用されている言語で関数またはメソッドを構築します。
于 2013-06-24T20:50:16.743 に答える
1

「アクティブ」ステータスを示す列でテーブルを汚染することはありません。Customersあなたが「アクティブ」と呼んでいるものは「ビジネス定義」であり、変更される可能性があります。また、そのような列のみが意味を持つのは、「今日の時点」のみです。期限切れのポリシーを取得するには、毎日 (おそらく深夜に) customer テーブルを UPDATE する必要があり、ポリシーがキャンセルされたときに UPDATE が必要になる場合があります。さらに、あなたのモデルは同じ顧客に対して複数のポリシーをサポートしているため (良いことです)、メンテナンスが面倒です。

また、先月の最初の「現在」のすべてのアクティブな顧客を検索したい場合 (典型的なクエリ) はどうでしょうか? 「アクティブ」ステータス列は役に立たないでしょう。

したがって、私の意見は次のとおりです。そのままにしておいてください。

于 2013-06-24T20:51:59.433 に答える
1

私はイエスと思う。あなたのDB設計は矛盾しています。DB をクリーンな状態に保つことを常にお勧めします。また、DB を最大正規形に保ちます。

ここで、「アクティブ」フラグを定期的に更新する代わりに、できることは 1 つあります。まず、Customers テーブルに「Active Till」列を追加します。ポリシーにレコードを追加するときよりも、「顧客」テーブルの [有効期限] が、追加されている現在のレコードの [有効期限] よりも前であることを確認する必要があります。はいの場合は、「ポリシーの現在の記録」に従って日付に変更します。そうでない場合は、変更しないでください。また、ユーザーがアクティブかどうかを確認する必要がある場合は、「Active Till」列を読んで決定してください。

于 2013-06-24T20:43:36.683 に答える
1

あなたが定義した基準がアクティブであることに関する唯一の基準である場合は、顧客のポリシー行を確認するだけで問題ないと思います。

アクティブ ステータスを計算するためのロジックがさらに多く、または高価なロジックがある場合は、これをプロセスの一部として計算し、Customers テーブルのアクティブ フィールドに格納する方がよい場合があります。

あなたが言及したものなど、他の決定要因がいくつかある可能性があり、ある方法が他の方法よりも優れていることをテストして確認するか、確固たるニーズのために特定の方法を好むかを決定するのは、実際にはアーキテクト次第です。

これは私が経験から学んだことであり、そうでないことを意味するルールを実際に見たことはありませんが、それが存在しないという意味ではありません。

于 2013-06-24T20:39:46.493 に答える
0

@duskwuff からのコメントに加えて...

現在、MS SQL データベースで同様のことを行っています。Googleで次の用語を入力することをお勧めします。

Database Normalization -oracle -mysql -db2

当然のことながら、Oracle や MySql を使用している場合は、これらのステートメントを -microsoft などで置き換えます。このコンテンツの一部は少し乾燥していますが、現在取り組んでいるデータベース プロジェクトを整理するのに役立ちました。

于 2013-06-24T21:32:57.350 に答える