循環依存を回避するためにこのデータベースを設計する方法は?


12

2つのテーブルがあります。

  1. ユーザー
  2. 住所

ユーザーには住所への参照が含まれています。

アドレスには、ユーザーへの参照である列CreatedByおよびModifiedByが含まれます。

周期的な依存関係を避けるために、このデータベースをどのように設計しますか?


4
ModifiedByは、アプリケーションユーザー(Userテーブルにある)ではなく、変更を行ったデータベースユーザーへの参照ではありませんか?いずれにせよ、それは本当に重要ではありません。実際の問題がある理由がわかりませんか?
フィリ

どちらが最初に作成されます。CreatedByおよびModifiedbyは必須データです。また、ユーザーテーブルのアドレスIDをnullにしないでください。鶏卵の問題。私は、ユーザーIDとのAddressIdのための参照を含む新しいテーブルUserAddressを作成することによってこの問題を解決したよう
シャシ

2
DBMSでサポートされている場合は、常に遅延制約を使用できます。
コリントハート

注:リレーショナルモデルは、2つの挿入または更新を1つのアトミック操作としてサポートしています。これは、SQLではサポートされていません(私が提案したにもかかわらず、遅延制約は非常に恐ろしいため)。
コリン

回答:


7

ヒントやトリック(遅延制約を含む)を検索する代わりに、この「参照ロック」から抜け出す方法を単純に設計することをお勧めします。次のようなものを試してください。


事実

  • ユーザー(UserID)が存在します。
  • アドレス(AddressID)Userによって作成されました(UserID)
  • 住所(AddressID)Dateに作成されました(DateCreated)
  • アドレスは(AddressID)最後で変更されたユーザー(UserID)日付(ModifiedOn)
  • ユーザー(UserID)DateからAddressに常駐しています。(AddressID)(ValidFrom)

制約

  • Each アドレスexactly one Userによって作成されました。It is possible that more than one アドレスthe same Userによって作成されました。

  • Each 住所exactly one Dateに作成されました。It is possible that more than one 住所the same Dateに作成されました。

  • For each 住所 and 日付that 住所はによって変更されたat most one ユーザーthat 日付

  • For each ユーザー and 日付that ユーザー日付以来at most one アドレスを常駐しています。that


論理的

ここに画像の説明を入力してください


必須アドレスに関する限り、アプリケーション層でそれを確認し、ロードステートメントをトランザクションにラップします。このようにして、すべてまたは何も取得しません。


5

最初のテーブルを作成するときに1つのテーブルが存在しないため、次の2つの操作で循環依存関係を作成することはできません。

CREATE TABLE A (A_ID INT PRIMARY KEY, B_FK INT);
CREATE TABLE B (B_ID INT PRIMARY KEY, A_FK INT REFERENCES A(A_ID));

ALTER TABLE A ADD B_FK INT;

循環依存を回避したい場合。次に、1つのREFERENCES制約を削除するか、DELETEとUPDATE CASCADE参照を1つの方法で追加できます。ロジックが多少複雑な場合は、TRIGGERを実装することもできます。


1
制約を削除すると、循環依存関係が定義から削除されますが、デザインは削除されません。イベントテーブルを追加して、アドレスを最後に作成または変更したUserIDとAddressIDを記録することもできますが、それは依存関係を1ステップ先に移動するだけです。逆に、UserテーブルにCreatedBy列とModifiedBy列がある場合、循環依存関係は1つのテーブルに存在します。これは、スーパーバイザーも従業員であるスーパーバイザー列を持つ従業員表に似ています。フィルが示したように-問題ありません。
リーリッフェル

@LeighRiffel同意します。ただし、提案するイベントテーブルは、実際にはすべての循環依存関係を削除します。
ypercubeᵀᴹ

@ypercube確かにそうです。どのようにワイヤーを渡したのか分かりません。明確にするために、巡回依存関係を削除しても、おそらくイベントテーブルを作成しないでください。
リーリッフェル

とにかく、私はこの答えが問題に対処するとは思わない。質問(私は思う)は、最初に循環パスを使用してFKを作成する方法ではなく、循環パスをまったく回避する方法についてです。
ypercubeᵀᴹ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.