web-dev-qa-db-ja.com

推移的な依存関係の何が問題になっていますか?

データベース設計に推移的な依存関係があります。上司から、これらはバグを引き起こす可能性があると言われました。これらの依存関係があるとバグがどのように発生するかを教えてくれるリソースを見つけるのが難しいと感じています。彼らはどのような問題を引き起こしますか?

私はその事実に異議を唱えているのではなく、彼らがどのような問題を引き起こす可能性があるのか​​を知りたがっています。

詳細については編集してください:

ウィキペディアから:

推移的な依存関係
推移的依存性は間接的な関数従属性であり、X→YおよびY→ZによってのみX→Zが存在します。

27
Simon Kiely

例で説明します:

-------------------------------------------------------------------
|  Course  |    Field     |   Instructor   |  Instructor Phone    |
-------------------------------------------------------------------
|  English |  Languages   |  John Doe      |     0123456789       |
|  French  |  Languages   |  John Doe      |     0123456789       |
|  Drawing |  Art         |  Alan Smith    |     9856321158       |
|  PHP     |  Programming |  Camella Ford  |     2225558887       |
|  C++     |  Programming |  Camella Ford  |     2225558887       |
-------------------------------------------------------------------
  • Courseがある場合は、そのInstructorを簡単に取得できるため、Course ->Instructorです。
  • Instructorがある場合、彼はさまざまなコースを教えている可能性があるため、そのCourseを取得することはできません。
  • Instructorがある場合は、彼のPhoneを簡単に取得できるので、Instructor->Phoneです。

つまり、Courseがある場合は、Instructor Phoneを取得できます。これはCourse ->Instructor Phoneを意味します(つまり、推移的な依存関係)

今問題のために:

  1. FrenchコースとEnglishコースの両方を削除すると、インストラクターJohn Doeも削除され、彼の電話番号は永久に失われます。
  2. 最初に彼のInstructorを追加しない限り、データベースに新しいCourseを追加する方法はありません。または、さらに悪いInstructors tableのデータを複製することもできます。
  3. インストラクターJohn Doeが電話番号を変更した場合は、彼が教えるすべてのコースを、間違いを起こしやすい新しい情報で更新する必要があります。
  4. インストラクターが教えるすべてのコースを削除するか、すべてのフィールドをnullに設定しない限り、データベースからインストラクターを削除することはできません。
  5. インストラクターの生年月日を維持することにした場合はどうなりますか? Birth DateフィールドをCoursesテーブルに追加する必要があります。これは論理的に聞こえますか?そもそもなぜコーステーブルにインストラクター情報を保持するのか。
50
Songo

3NFを表現する1つの方法は次のとおりです。

すべての属性は、キー、キー全体、およびキーのみに依存する必要があります。

推移的な依存関係X-> Y-> Zはその原則に違反し、データの冗長性と潜在的な変更の異常につながります。


これを分解しましょう:

  1. 定義によるFunctional依存性X-> Y-> Zもまたはtransitive 、X <-Yはnot保持する必要があります。
  2. Yがキーの場合、X <-Yが保持されるため、Yをキーにすることはできません。(FOOTNOTE1)
  3. Yはキーではないため、任意のYを複数の行で繰り返すことができます。
  4. Y-> Zは、同じYを保持するすべての行が同じZも保持する必要があることを意味します。(FOOTNOTE2)
  5. same(Y、Z)タプルを複数の行で繰り返しても、システムに役立つ情報は提供されません。 冗長です。

つまり、Yはキーではなく、Y-> Zであるため、3NFに違反しています。

冗長性は変更の異常につながります(たとえば、同じYに「接続された」Zの一部すべてではないを更新すると、どのコピーが正しいかわからなくなるため、本質的にデータが破損します)。これは通常、元のテーブルを2つのテーブルに分割することで解決されます。1つは{X、Y}を含み、もう1つは{Y、Z}を含みます。このように、Yは2番目のテーブルのキーになり、Zは繰り返されません。

一方、X <-Yが成立する場合(つまり、X-> Y-> Zが推移的でない場合)、XとYの両方がキーである単一のテーブルを保持できます。このシナリオでは、Zが不必要に繰り返されることはありません。

(FOOTNOTE1)キーは、リレーション内のすべての属性を機能的に決定する(最小限の)属性のセットです。理論的根拠:Kがキーである場合、Kの値が同じである複数の行は存在できないため、Kの任意の値は、常に他のすべての属性の1つの値に正確に関連付けられます(1NFを想定)。定義上(脚注2を参照)、「正確に1つに関連付けられている」とは、「機能依存性にある」と同じです。

(FOOTNOTE2) 定義による 、Y-> Z各Y値が正確に1つのZ値に関連付けられている場合に限ります。


例:

各メッセージに1人の作成者がいて、各作成者に1つのプライマリ電子メールがあるとすると、同じテーブルでメッセージとユーザーを表現しようとすると、電子メールが繰り返されます。

MESSAGE                         USER    EMAIL
-------                         ----    -----
Hello.                          Jon     [email protected]
Hi, how are you?                Rob     [email protected]
Doing fine, thanks for asking.  Jon     [email protected]

(実際には、これらはMESSAGE_IDsですが、ここでは簡単にしましょう。)

さて、ジョンが自分の電子メールを「[email protected]」などに変更することにした場合はどうなりますか? Jonの行のbothを更新する必要があります。 1つだけ更新すると、次のような状況になります...

MESSAGE                         USER    EMAIL
-------                         ----    -----
Hello.                          Jon     [email protected]
Hi, how are you?                Rob     [email protected]
Doing fine, thanks for asking.  Jon     [email protected]

...そして、Jonの電子メールのどれが正しいかはもうわかりません。私たちは本質的にデータを失いました!

DBMSに両方の更新を強制するために使用できる宣言型の制約がないため、状況は特に悪いです。クライアントコードwillにはバグがあり、おそらく並行環境で発生する可能性のある複雑な相互作用をあまり考慮せずに記述されています。

ただし、テーブルを分割すると...

MESSAGE                         USER
-------                         ----
Hello.                          Jon 
Hi, how are you?                Rob 
Doing fine, thanks for asking.  Jon 

USER    EMAIL
----    -----
Jon     [email protected]
Rob     [email protected]

...現在、Jonの電子メールを知っている行は1つしかないため、あいまいさはありません。

ところで、これはすべて DRY原則 の単なる別の表現と見なすことができます。

10

テーブルに推移的な依存関係がある場合、それは3NFに準拠していません。したがって、テーブルに冗長データがある可能性が高くなります。 this をチェックして、この概念を明確にしてください。

このリンクを見てください:

http://en.wikipedia.org/wiki/Transitive_dependency

例を使用すると、ジュールヴェルヌの国籍を一方の行で更新し、もう一方の行では更新しないとどうなりますか?著者の国籍は、本と著者の組み合わせではなく、著者のみによって決定されます。したがって、データ構造の例を使用すると、データベースにジュール・ヴェルヌの国籍を尋ねることができます。次のSQLコマンドを実行した場合

SELECT TOP 1 author_nationality FROM books WHERE author = 'Jules Verne'

データベースがTOP1を選択する方法に応じて、異なる答えを得ることができます。

3
Sparky

推移的な依存関係が一般的に悪い考えである理由を取り上げた投稿をまとめました: http://www.essentialsql.com/get-ready-to-learn-sql-11-database-third-normal-form -explained-in-simple-english /

1
Kris Wenzel