1. ホーム
  2. database-design

[解決済み] ノーマライゼーション(または正規化)とは?[クローズド]

2022-10-28 19:53:36

質問

なぜデータベースの人は正規化について語るのでしょうか?

それは何ですか?どのように役立つのでしょうか?

データベース以外のものにも適用されるのですか?

どのように解決するのですか?

正規化とは、基本的にデータの重複や冗長性を避けるようなデータベーススキーマを設計することです。同じ情報がデータベース内の複数の場所で繰り返されると、ある場所では更新されても他の場所では更新されないというリスクがあり、データの破損につながります。

正規化には、1.正規形から5.正規形までのレベルがあります。それぞれの正規形は、ある特定の問題を取り除く方法を記述しています。

第一正規形(1NF)は、冗長性についての問題ではないので、特別なものです。1NFは入れ子になったテーブル、より具体的にはテーブルを値として許可する列を禁止しています。入れ子のテーブルはそもそも SQL でサポートされていないので、通常のリレーショナル データベースの多くはデフォルトで 1NF になっています。ですから、残りの議論では1NFを無視することができます。

2NFから5NFの正規形はすべて、同じ情報が同じテーブルで複数回表現されるシナリオに関係しています。

例えば、月や惑星のデータベースを考えてみましょう。

Moon(PK) | Planet  | Planet kind
------------------------------
Phobos   | Mars    | Rock
Daimos   | Mars    | Rock
Io       | Jupiter | Gas
Europa   | Jupiter | Gas
Ganymede | Jupiter | Gas

冗長性は明らかです。木星がガス惑星であるという事実が、それぞれの月について3回繰り返されます。これはスペースの無駄ですが、もっと深刻なのはこのスキーマによって 一貫性がない 情報を可能にします。

Moon(PK) | Planet  | Planet kind
------------------------------
Phobos   | Mars    | Rock
Deimos   | Mars    | Rock
Io       | Jupiter | Gas
Europa   | Jupiter | Rock <-- Oh no!
Ganymede | Jupiter | Gas

クエリが一貫性のない結果を出すことができるようになり、悲惨な結果になる可能性があります。

(もちろん、データベースは 間違った が入力されるのを防ぐことはできません。しかし 一貫性のない の情報は保護できますが、これは同様に深刻な問題です)。

正規化された設計では、テーブルを2つのテーブルに分割することになります。

Moon(PK) | Planet(FK)     Planet(PK) | Planet kind
---------------------     ------------------------
Phobos   | Mars           Mars       | Rock
Deimos   | Mars           Jupiter    | Gas
Io       | Jupiter 
Europa   | Jupiter 
Ganymede | Jupiter 

これでどのファクトも複数回繰り返されることはなくなり、データに矛盾が生じる可能性はなくなりました。(惑星名が繰り返されるのでまだ繰り返しがあるように見えるかもしれませんが、主キーの値を外部キーとして繰り返しても、不整合データのリスクは発生しないので正規化に違反しません)。

経験則 もし同じ情報がより少ない個々のセル値で表現できるのであれば、外部キーを除いて、テーブルをより多くのテーブルに分割することによって正規化されるべきである。たとえば、最初のテーブルには 12 の個別値がありますが、2 つのテーブルには 9 の個別値 (非 FK) があるだけです。これは、3つの冗長な値を排除することを意味します。

を書けばよいので、同じ情報が残っていることがわかります。 join クエリを書くことができ、そのクエリは元の正規化されていないテーブルと同じデータを返すので、同じ情報が残っていることがわかります。

このような問題を避けるにはどうしたらよいでしょうか? 正規化の問題は、概念モデルに少し工夫をすること、例えば、実体関係図を描くことで簡単に回避できます。惑星と月は一対多の関係にあり、外部キー・アソシエーションを持つ2つの異なるテーブルで表現されるべきことを意味します。正規化の問題は、一対多または多対多の関係を持つ複数のエンティティが同じテーブル行で表現される場合に発生します。

正規化は重要ですか? はい、そうです。 非常に 重要です。正規化エラーがあるデータベースを使用すると、無効なデータや破損したデータをデータベースに取り込む危険性があります。データは永遠に生き続けるので、破損したデータがデータベースに入った場合、それを取り除くことは非常に困難です。

しかし、2NFから5NFまでの異なる正規形を区別することが重要だとは、私はあまり思いません。スキーマに冗長性がある場合は、通常、かなり明白です。問題が修正される限り、違反しているのが3NFか5NFかはあまり重要ではありません。

(DKNFや6NFのような追加の正規形もありますが、これはデータウェアハウスのような特別な目的のシステムにのみ関係するものです。)

正規化を怖がらないで . 正規化レベルの公式な技術的定義は、かなり難解です。まるで正規化が複雑な数学的プロセスであるかのような印象を与えています。しかし、正規化とは基本的に単なる常識であり、常識を使ってデータベース スキーマを設計すれば、通常、完全に正規化されることがわかります。

正規化には多くの誤解があります。

  • 正規化されたデータベースはより遅く、非正規化によってパフォーマンスが向上すると信じている人もいます。しかし、これは非常に特殊なケースにのみ当てはまります。通常、正規化されたデータベースは最速でもあります。

  • 時々、正規化は段階的な設計プロセスとして説明され、あなたは"いつ止めるか"を決定する必要があります。しかし実際には、正規化レベルは異なる特定の問題を記述するだけです。第3 NF以上の正規形によって解決される問題はそもそもかなり稀な問題なので、あなたのスキーマがすでに5NFである可能性はあります。

データベース以外のものにも適用されるのでしょうか? 直接的にはありません。正規化の原則は、リレーショナル データベースにかなり特化したものです。しかし、一般的な基本テーマである「異なるインスタンスが同期を失う可能性がある場合、重複したデータを持つべきではありません」は、広く適用することができます。これは基本的に DRY 原則 .