今日、私は3NF分解アルゴリズムについて読みました。と言いました:
- Fの最小基底を見つける、Gと言う
- Gの各FD X→Aについて、分解の関係の1つのスキーマとして{X、A}を使用します
- 手順2の関係のセットのいずれもRのスーパーキーではない場合、スキーマがRのキーである別の関係を追加します。
この関係を3NFに分解したい。
R(A,B,C)
S={A→B, A→C, B→A, B→C, C→A, C→ B, AB→ C, BC→A, AC→B, A→BC, B→AC, C→AB}
ご覧のとおり、Rのキーは{A},{B},{C}
[〜#〜] s [〜#〜]には、次のようないくつかの最小基準があります。
{A→B, B→A, B→C, C→B}
;そして{A→B, B→C, C→A}
問題は、最初の最小基底を使用する場合、Rを2つの関係に分解します:(A、B)、(B、C)。
2番目の最小基底を使用すると、Rは(A、B)、(B、C)、(C、A)になります。
私の質問は、どちらが正しいですか?
まず、元の関係はすでに第3正規形になっていることに注意してください。各属性は素数(実際には各属性がキー)であるため、3NFの定義が尊重されます。
次に、アルゴリズムが不完全であることに注意してください。手順は次のとおりです。
- Fの最小基底を見つける、Gと言う
- 左部分が同じFDの各グループについて、X→A1、X→A2、...、X→Aん Gでは、{X、A1、A2、...、Aん}分解の関係の1つのスキーマとして
- 属性が別のリレーションに含まれているすべてのリレーションを削除します。
- 手順2のリレーションセットのいずれもRのスーパーキーではない場合は、スキーマがRのキーである別のリレーションを追加します。
したがって、最初のケースでは、依存関係の3つのグループを取得します。
A → B
B → A
B → C
C → B
3つの関係、R1(A、B)、R2(A、B、C)、R3(B、C)、そしてアルゴリズムに従って、結果としてRのみを取得します2、他の2つには属性が含まれているため。
したがって、使用される最小ベースに応じて、アルゴリズムから2つの異なる出力があります(これは、最小カバーを計算するときに依存関係を考慮する順序に依存します)。
だから、あなたの質問への答え:
どちらが正しいか?
is:両方とも正しい、両方とも3NFの定義を満たすため。 3NFで関係を分解するための合成アルゴリズムがさまざまなソリューションを生成できることを単に発見しました。
別の質問は、「より良い」であり、クエリを作成するときにテーブルを結合する必要がないため、単一のリレーションを使用したソリューションの方が「より良い」ということです。
もちろん、関係がすでに3NFにあるかどうかを最初に確認できれば、アルゴリズムを適用することを避けることができます。しかし、これは一般的に行うことができません。関係の主要な属性を見つけるために、チェックではすべてのキーの指数計算が必要になるためです。