1

適切に正規化されていない古いデータベースを維持する必要があります。たとえば、注文から納品日までのプロジェクトのさまざまなマイルストーンに対して、5つ以上の異なる日付列を持つように成長した(またはキノコになっている)プロジェクトテーブルがあります。番地、メールアドレス、またはWebリンクの列がそれぞれにあるテーブルもいくつかあります。

構造を正規化し、住所や予定日などのテーブルを作成し、1:Nの関係(顧客ごとの住所、プロジェクトごとの期日など)を可能にするために必要なテーブルを作成したいと思います。

現在、詳細テーブルのデータへの変更を処理する方法が完全にわかりません。たとえば、顧客の配送先住所の変更について考えてみます。複数のレコード(場合によっては複数のテーブル内)がそのレコードを参照する可能性があるため、アドレステーブルのデータを変更することは問題外です。新しいアドレスレコードを追加すると、他の行に外部キー関係がない場合、古いレコードが孤立したままになる可能性があります。

私はこれを処理するために次の方法について考えました:

  • 新しい詳細レコードを追加し、マスターテーブルの更新トリガーをチェックインして、古い詳細レコードを削除する必要があるかどうかを確認します。これには、詳細テーブルと関係のあるすべてのテーブル、それらすべて、またはsprocに関する知識が必要になります。私はこの分離の喪失が好きではありません。また、アクティブなトランザクションにより多くのテーブルが含まれます。

  • トリガーに古い詳細レコードの削除を試みさせ、エラーをキャッチします。これはただ間違っていると感じます。

  • 孤立したレコードを使用して、定期的なメンテナンスタスクですべての詳細テーブルをクリーンアップします。

複数のマスターテーブルにリンクされている詳細テーブルのデータ変更を処理するための推奨される方法は何ですか?これを読むためのヒントはありますか?

4

3 に答える 3

6

問題の一部は、元のスキーマ設計である可能性があります。外部キーが間違った方向を指し、住所や電話番号などを詳細ではなくマスターとして扱います。これは、特定のアドレスのすべての使用を一度に更新する場合に便利ですが、私の経験では、常に非常に多くの困難な例外的なケースに発展します。たとえば、ある場所にいる1人が移動するため、全体に対してリンクを解除する必要があります。世帯またはオフィスが移動するため、既存のレコードを更新します。CRUD画面でユーザーからこの詳細を非表示にしようとすると、目的の機能が実行されない状況になります。

重複する値を折りたたむためだけにそのように行われた場合、それは事実上データベースの非正規化です。アドレス行が存在するだけでは意味がありません。唯一の違いは、ほとんどの非正規化とは異なり、速度ではなくスペース効率を上げようとすることです。その時点でリンクテーブルを作成することは、単に問題を悪化させます。

たとえば、連絡先ごとに複数の住所が必要な場合は、親の連絡先を指す外部キーを使用して住所を詳細テーブルにします。住所の値は単なる値であるため、重複する心配はありません。それ以外の場合は、アドレスを実際のエンティティにします。タイトルまたは説明フィールドとCRUD画面を追加して、エンティティとして独立できるようにします。

于 2009-01-15T22:02:29.743 に答える
3

孤立したレコードを維持し、定期的なメンテナンス タスクですべての詳細テーブルをクリーンアップします。

于 2009-01-15T21:49:50.440 に答える
0

削除と更新のケースを曖昧にしていると思います。

クライアントaとクライアントbがあり、両方が同じアドレスを使用している場合、それはリレーショナルテーブルのレコードに反映されます(たとえば、ClientAddressesですが、複数のエンティティのアドレスを格納している場合は、より複雑になると思います。それ)

2つのクライアントが共有してアドレスを指定し、クライアントaに対して正しくない場合、クライアントbに対しても正しくないと思います(つまり、データ入力エラー)が、クライアントに変更を加えたくない場合は、ベースアドレス情報を取得し、関連付けレコードを削除して(ClientAddressesから削除)、新しいアドレスを追加します。リレーショナルテーブルから(おそらくストアドプロシージャから)削除を実行するときは、ベーステーブルから削除しない場合は、関連付けが解除されているアドレスレコードを参照している他のレコードがあるかどうかを確認します。

于 2009-01-15T22:07:17.707 に答える