web-dev-qa-db-ja.com

例で6NFを理解したい

@PerformanceDBAの引数re:6NFとE-A-Vを読んだところです。興味をそそられます。テーブルにいくつかのタイムスタンプ列を「単に」貼り付けるものとして提示されたため、以前は6NFに懐疑的でした。

私は常にデータディクショナリを使用してきました。データディクショナリを使用したり、SQLコードを生成したりする必要はありません。したがって、コードの生成に使用される辞書(またはカタログ)を必要とする答えを期待しています。

6NFが非常にの簡単な例をどのように処理するかを知りたいのですが。アイテム、説明、価格の表。価格は時間とともに変化します。

とにかく、6NFに変換すると、Itemsテーブルはどのように見えますか? 「テーブルの爆発」とは何ですか?それはここで起こりますか?

例がこのように単純なテーブルで機能しない場合は、要点を理解するために必要なものを自由に追加してください。

41
Ken Downs

簡単に言えば、6NFは、すべてのリレーションが候補キーと1つ以上の他の(キーまたは非キー)属性で構成されることを意味します。たとえば、「商品」がProductCodeで識別され、他の属性がDescriptionとPriceである場合、6NFスキーマは2つの関係で構成されます(*はそれぞれのキーを示します)。

ItemDesc {ProductCode*, Description}
ItemPrice {ProductCode*, Price}

これは依存関係を最小限にするため、潜在的に非常に柔軟なアプローチです。ただし、これは特にSQLデータベースでの主な欠点でもあります。 SQLでは、複数のテーブル制約を強制することが困難または不可能になります。上記のスキーマを使用すると、ほとんどの場合、すべての製品に常に説明と価格が必要であるというビジネスルールを適用することはできません。同様に、適用すべき複合キーを強制できない場合があります(属性が複数のテーブルに分割される可能性があるため)。

したがって、6NFを検討する際には、どの依存関係と整合性ルールが重要かを検討する必要があります。多くの場合、5NFに固執し、それ以上は正規化しない方がより実用的で便利な場合があります。

31
nvogel

私は実際に答えをまとめ始めましたが、あなたは(当然のことながら)簡単な例を望んでいるので、複雑に遭遇しました。問題は多様です。

まず、リレーショナルデータベースと5NFに関する実際の専門知識のレベルについては、私にはよくわかりません。 6NFの詳細を取り上げて議論するための出発点はありません。

第2に、他のNFと同様に、多彩です。かろうじてそれに入ることができます。 certanテーブルに6NFを実装できます。すべてのテーブルを完全に独り占めすることができます。テーブルが爆発することは確かですが、それを正規化して、爆発を殺します。これは、6NFの高度なまたは成熟した実装です。最も単純で最も単純な例を求めている場合、6NFの完全なレベルまたは部分的なレベルを提供する意味はありません。

他のテーブルが「6NF」である場合もあれば、「5NFで」存在することもあると理解していると思います。

だから私はあなたのために一つをまとめました。しかし、それでも説明が必要です。

現在、SQLは5NFをほとんどサポートしていませんが、6NFをまったくサポートしていません(dportasが同じことを別の言葉で言っていると思います)。パフォーマンス上の理由から、6NFを深いレベルで実装します(ピボット(MSのばかげたPIVOT関数ではなく、テーブル全体のすべての列)の単純化)、列アクセスなど。そのためには、完全なカタログが必要です。 SQLカタログの拡張、SQLがサポートしていない6NFをサポートし、データの整合性とビジネスルールを維持します。したがって、楽しみのために6NFを実際に実装したくはありません。カタログを実装する必要があるため、必要な場合にのみ6NFを実装します。 (これがEAV群衆が行わないことであり、これがほとんどのEAVシステムにデータ整合性の問題がある理由です。それらのほとんどは宣言参照を使用しません) &SQLが持つデータの整合性。)

しかし、6NFを実装するほとんどの人は、完全なカタログで、より深いレベルを実装しません。それらはより単純なニーズを持っているため、より浅いレベルの6NFを実装します。それでは、簡単な例を示しましょう。 5NFであると宣言されている通常のProductテーブルから始めましょう(5NFについては議論しません)。会社はさまざまな種類の製品を販売しており、半分の列は必須で、残りの半分はオプションです。つまり、製品タイプによっては、特定の列がNullになる場合があります。彼らはデータベースで良い仕事をしたかもしれませんが、Nullは今や大きな問題です:特定のProductTypesに対してNot Nullであるべき列はNullです。なぜなら、宣言はNULLを示し、アプリのコードは次の人のものと同じです。

そのため、彼らは6NFを使用してその問題を修正することを決定しました。6NFのサブタイトルは、それがThe Null Problemを排除すると述べているためです。 6番目の正規形は既約正規形であり、データをさらに正規化することはできないため、この後のNFはありません。行は最大限に正規化されています。 6NFの定義は次のとおりです。

行に主キーと最大で1つの属性が含まれている場合、テーブルは6NFになります

その定義により、地球全体の何百万ものテーブルがその意図なしにすでに6NFにあることに注意してください。例えば。 PKと説明のみの典型的な参照または参照テーブル。

正しい。さて、私たちの友達は8つの非キー属性を持つProductテーブルを見て、彼らがProductテーブルを6NFにすると、8つのサブProductテーブルを持つことになります。次に、一部の列が他のテーブルへの外部キーであり、さらに複雑になるという問題があります。そして彼らは、SQLが彼らのしていることをサポートしておらず、小さなカタログを作らなければならないという事実に注意しています。 8つのテーブルは正しいですが、賢明ではありません。彼らの目的は、ヌルを取り除くことであり、各テーブルの周りに小さなサブシステムを書くことではありませんでした。

シンプルな6NFの例

リレーショナルデータベースのモデリングの標準に不慣れな読者は、例の記号を解釈するために IDEF1X Notation が役立つかもしれません。

したがって、通常、製品テーブルはすべての必須列、特にFKを保持し、各オプション列、各Nullable列は個別のサブ製品テーブルに配置されます。それが私が見た中で最も単純な形です。 8つではなく5つのテーブル。モデルでは、4つのサブ製品テーブルは「6NF内」にあります。メインのProductテーブルは「5NF」です。

これで、ProductTypeなどに基づいて、Productから選択するすべてのコードセグメントが、どの列を構築する必要があるかを理解する必要がないので、Productテーブルクラスタの5NF "ビュー"を提供するビューを提供します。 。

次に必要なのは、SQLカタログの拡張機能の基本的な基礎です。これにより、さまざまなProductTypeのルール(データの整合性)が、アプリのコードに依存せずに、データベース内の1か所で確実に維持されます。あなたが逃げることができる最も単純なカタログ。これはProductTypeから派生しているため、ProductTypeはそのメタデータの一部を形成しています。あなたはカタログなしでその単純な構造を実装することができますが、私はそれをお勧めしません。

更新

データベースにallビジネスルールを実装していることに注意してください。それ以外の場合はデータベースではありません(「アプリケーションコードで」ルールを実装するという概念は、特に、今日、「開発者」として働いている花屋がいる場合、陽気です)。したがって、すべてのルールなどは何よりもまずSQL宣言、CHECK制約、関数などとして実装されます。これにより、すべての宣言参照整合性と宣言データ整合性が保持されます。 SQLカタログの拡張は、SQLが宣言を持たない領域をカバーし、SQLとして実装されます。優れたデータディクショナリであるため、さらに多くのことができます。例えば。テーブルを変更したり、列やその特性を追加または変更したりするたびにビューを作成するのではなく、単純なコードジェネレーターを使用して、カタログ+拡張から直接作成されます。

もう1つ非常に重要な注記。完全かつ忠実な正規化の演習を完了せずに、5NFに6NF(またはEAVを正しく)を実装することはできません。私がすべてのサイトで目にする問題は、本物の5NF状態ではなく、部分的な正規化のミッシュマッシュがあるか、まったく正規化されていないことですが、それらは非常に関連しています。それから6NFまたはEAVのいずれかを作成することは災難です。それからEAVまたは6NFを作成する宣言型SQLで実装されたすべてのビジネスルールなしでは、何年にもわたる核災害です。あなたはあなたが支払うものを手に入れます。

更新を終了します。

最後に、はい、さらに4つの正規化レベルがあります(正規化は原則であり、単なる正規形への参照ではありません)。これは、その単純な6NF製品クラスターに適用でき、より多くの制御、より少ないテーブルなどを提供します。深く行くほど、カタログはより広範囲になります。そして、より高いレベルのパフォーマンス。あなたが準備ができたら、聞いてください、私はすでにモデルを組み立て、他の回答に詳細を投稿しました。

43
PerformanceDBA

テーブルにいくつかのタイムスタンプ列を「単に」貼り付けるものとして提示されたため、以前は6NFに懐疑的でした。

この明らかな誤解がどこから来ているのか、私にはよくわかりません。おそらく、6NFが日付、ダーウェン、ロレンツォスの著書「時系列データと関係モード」に導入されたという事実でしょうか。とにかく、ここでの他の回答が6NFが一時的なデータベースに限定されないことを明らかにしたことを願っています。

私が言いたかった点は、6NFは「学問的に立派な」ものであり、常に達成可能ですが、必ずしもSQLを使用した実装を検討するときだけでなく、必ずしも最適な設計につながるとは限らないということです。前述の6NFの発見者と支持者でさえ、同意しているようです。

Chris Date :「実際には、5NF(および6NF)を使用してください。」

Hugh Darwen :「日付の周りの6NF分解[人ではない!]はやりすぎです...サッカークラブの最適な設計は... 5-and-a-bit-NF!」

Hugh Darwen :「5NFにはいるが6NFにはない。ここでも5NFで十分」(同じような例がいくつかあります)。

次に、反対の証拠を見つけることもできます。

Chris Date :「Darwenと私はしばらくの間、すべてのベースrelvarが6NFである必要があると感じていました。」.

実際問題として、最近、ある製品のSQLスキーマを拡張して、マイナーな機能を追加しました。私はnull可能列を回避するために6NFを採用し、最終的に6つの新しいテーブルができました。私の同僚のほとんど(全員?)は、null可能列を持つ1つのテーブル(またはおそらく既存のテーブルを拡張)を使用していました。いくつかの「ヘルパー」スト​​アドプロシージャと「非正規化」VIEWINSTEAD OFトリガー、SQLレベルでこの機能を使用する必要があったすべてのコーダーは、私を呪うために邪魔になりません:)

6
onedaywhen

これらの人はそれをダウンさせています: アンカーモデリング 。主題に関する優れた学術論文と実践的な例。彼らの執筆により、ようやく私はエッジを超えて、次のプロジェクトで6nfに [〜#〜] dw [〜#〜] を構築することを検討するようになりました。 [〜#〜] poc [〜#〜] 私が行った作業は、6nfの莫大な利点がコストを上回らないことを(少なくとも私にとっては)検証しました。

3
Brian