2009-08-17 24 views
4

私の最初の質問はすごくいいです!ナチュラルキーを使用するか、監査/変更ログにサロゲートキーと監査テーブルを使用してください

私は経験の少ないジュニア開発者であり、この問題に問題があります。

監査可能にする必要があるテーブルがあります。この表にコールセンターによる電話の記録が記録されているとしましょう(これは単なる例ではありません)。私はそれを "CallHistory"と呼ぶでしょう。

私はもともと、呼び出し先の名前、電話番号などを持つ「呼び出し先」という別のテーブルを保持する予定でした。このテーブルは代理の主キーを使用していました。

CallHistoryテーブルは、Calleeテーブルへの外部キーを持ちます。

私は元の電話番号を変更した場合、システム全体に伝播し、複数のテーブルで電話番号を変更する必要がないように、もともとこれを行いました。

問題は、CallHistoryテーブルの全体的なポイントは、間違った番号の呼び出し(誤った番号を呼び出した呼び出し元など)の履歴を記録することです。履歴は、この代理キーアプローチを使用して失われます。

作業中のシニア開発者の一人は、履歴を保存するためにCallHistoryテーブルにその特定の時刻に発信者のダイヤルごとに電話番号のコピーを保持することを提案しました。

私は同じ目的のために監査/変更ログテーブルを保持することを考えていました。

私のアプローチはこのプルプスに十分であろうか、それとも完全にオフトラックですか?どのアプローチが好きですか?

乾杯、 アンドリュー

答えて

1

私はRikに同意します。はい、冗長なデータは非常に、非常に悪い、邪悪な、臭い、そうでなければ望ましくないです。しかし、2つのフィールドが「電話番号」と呼ばれているだけで、同じものにはなりません。 「顧客の現在の電話番号」と「最後に話したときの顧客の電話番号」は必ずしも同じものではありません。

私は現在、販売およびアイテム情報を保持するデータベースを使用しています。品目レコードには、説明、在庫番号、価格などの情報が含まれます。当社の販売記録には、説明、在庫番号、および価格も含まれています。説明と在庫番号は冗長であり、削除する必要があります。これは悪いデザインだった。しかし価格は両方の場所に含める必要があります。特定の販売時点では、現在の価格と価格との間に大きな違いがあります。その売却は数年前のことかもしれない。それ以来、価格は数十回変化している可能性があります。

一般的に、あなたの説明のようなアプリケーションでは、私は電話番号を履歴テーブルに入れ、それを使って完了します。 「電話番号履歴」テーブルを持ち、該当する時の電話番号レコードにリンクすることで得られることはほとんどありません。レコードごとに数バイトを節約できるかもしれませんが、複雑さが増します。しかし、関連するフィールドが複数ある場合は、ストーリーが変わります。例えば、あなたが健康保険会社であり、州の法律が違うこと、地域の医師がいることなどのために、地域によってその保険範囲が異なることなど、顧客が移動するときにポリシーを書き直す必要があるため、電話番号は他の多くのデータ項目と関連する可能性があるため、すべてが単一のテーブルに入れられ、適切なレコードにリンクする必要があります。それ以外の場合は、ニュージャージー州の電話番号を持つことができますが、カリフォルニアの保険契約条件などにリンクしています。

1

あなたの質問は非常に典型的な設計のジレンマです。たとえば、データベースが通常の形式であり、販売、マネージャー(売り手)、地域(マネージャーが働いている場所)のテーブルがあるとします。 「地域ごとにグループ化された毎年の売上」のようなレポートを作成しています。しかし、マネージャーの1人がその年の間に別のオフィスに移転すると、レポートに間違ったデータが表示されるようです。

いくつかのケースでは3つのソリューション

1)がどのようなものがあり、開発者やアナリストが決める:まあ、我々のデータは非常に正確ではないですが、今、私たちは通常、フォームに滞在し、データを複製していない欲しいのはOKです。この解決法はそれほど複雑ではありません。この場合、通常のフォームでCallersとCallHistoryテーブルを作成できます。つまり、電話番号はCallersテーブルのみになります。

2)過去の変更を失わないという要件があります。また、私たちのレポートとクエリが(データベースサイズを犠牲にして)非常に高速になるようにしたいと考えています。この場合、人々はすべてのフィールドを複製することにします。たとえば、電話番号、発信者名、住所などを含むCallHistoryテーブルを作成することができます。これは、これらの各フィールドが将来変更される可能性があるためです。もちろん、Calleeテーブルを作成することもできます(別の目的のために必要になるかもしれません)が、CallHistoryによって再定義されている可能性があります。いくつかのレコードをCalleeから削除する必要があるがCallHistoryに入れる必要があると考えるとします。これは、開発者がデータの参照整合性に違反する可能性があると考えることが多く、CallHistoryテーブルから外部キーを作成しない場合です。これは合理的です。なぜなら、外部キーがなければ、挿入がより速く動作するからです。

3)私はもっと好きですが、実装の観点から見ると最も複雑です。CallHistoryテーブルはCalleeHistoryテーブルを参照する必要があります。 CalleeHistoryテーブルには、Calleeテーブルにあるすべてのファイルがありますが、CalleeID + DateModified(DateModified開発者の代わりにModificationVersionNumberを使用する)のような代理キーもあります。 CallHistoryには、CalleeID + DateModifiedを参照する代理外部キーがあります。この場合、データは正規化されています(電話番号は別のテーブルに公開されていません)。過去の変更は失われませんでした。

私が言っていた限り、実装、データベースのパフォーマンス、データベースのサイズ、データの整合性、システムに対する機能的な要件の複雑さには、しばしばトレードオフがあります。ジュニア開発者の場合は、考えられるすべての解決策を念頭に置いておきましょう。おそらく、スタックオーバーフローの誰よりもあなたのシステムと要件について知っているシニア開発者の意見に耳を傾けるべきでしょう。

P.S.

あなたはおよそゆっくりと寸法を変え読み、他のアプローチについて知りたい場合は、たとえばhttp://en.wikipedia.org/wiki/Slowly_changing_dimension

2

のために私はあなたがここに正規形に関する繊細に惑わされていると思います。問題は、着信者に関連付けられた電話番号はで、発信者がダイヤルした番号と同じ情報ではありません。です。一般的なケースでは同じ値を持つかもしれませんが、これは別の問題です。

私の意見では、CallHistoryにはnumbreとダイヤルされた表の両方が必要です。

関連する問題