データベース設計に推移的な依存関係があります。上司から、これらはバグを引き起こす可能性があると言われました。これらの依存関係があるとバグがどのように発生するかを教えてくれるリソースを見つけるのが難しいと感じています。彼らはどのような問題を引き起こしますか?
私はその事実に異議を唱えているのではなく、彼らがどのような問題を引き起こす可能性があるのかを知りたがっています。
詳細については編集してください:
ウィキペディアから:
推移的な依存関係
推移的依存性は間接的な関数従属性であり、X→YおよびY→ZによってのみX→Zが存在します。
例で説明します:
-------------------------------------------------------------------
| 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
を意味します(つまり、推移的な依存関係)
今問題のために:
French
コースとEnglish
コースの両方を削除すると、インストラクターJohn Doe
も削除され、彼の電話番号は永久に失われます。Instructor
を追加しない限り、データベースに新しいCourse
を追加する方法はありません。または、さらに悪いInstructors table
のデータを複製することもできます。John Doe
が電話番号を変更した場合は、彼が教えるすべてのコースを、間違いを起こしやすい新しい情報で更新する必要があります。Birth Date
フィールドをCourses
テーブルに追加する必要があります。これは論理的に聞こえますか?そもそもなぜコーステーブルにインストラクター情報を保持するのか。3NFを表現する1つの方法は次のとおりです。
すべての属性は、キー、キー全体、およびキーのみに依存する必要があります。
推移的な依存関係X-> 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_ID
sですが、ここでは簡単にしましょう。)
さて、ジョンが自分の電子メールを「[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原則 の単なる別の表現と見なすことができます。
テーブルに推移的な依存関係がある場合、それは3NFに準拠していません。したがって、テーブルに冗長データがある可能性が高くなります。 this をチェックして、この概念を明確にしてください。
このリンクを見てください:
http://en.wikipedia.org/wiki/Transitive_dependency
例を使用すると、ジュールヴェルヌの国籍を一方の行で更新し、もう一方の行では更新しないとどうなりますか?著者の国籍は、本と著者の組み合わせではなく、著者のみによって決定されます。したがって、データ構造の例を使用すると、データベースにジュール・ヴェルヌの国籍を尋ねることができます。次のSQLコマンドを実行した場合
SELECT TOP 1 author_nationality FROM books WHERE author = 'Jules Verne'
データベースがTOP1を選択する方法に応じて、異なる答えを得ることができます。
推移的な依存関係が一般的に悪い考えである理由を取り上げた投稿をまとめました: http://www.essentialsql.com/get-ready-to-learn-sql-11-database-third-normal-form -explained-in-simple-english /