この記事では、初心者向けのデータベース正規化の用語について説明します。 この用語の基本的な理解は、リレーショナル データベースの設計について説明する際に役立ちます。
正規化の説明
正規化は、データベース内のデータを整理するプロセスです。 これには、データを保護し、冗長性と一貫性のない依存関係を排除することでデータベースの柔軟性を高めるために設計されたルールに従って、テーブルの作成とテーブル間のリレーションシップの確立が含まれます。
冗長データによってディスク領域が無駄になり、メンテナンスの問題が発生します。 複数の場所に存在するデータを変更する必要がある場合は、すべての場所でまったく同じ方法でデータを変更する必要があります。 顧客アドレスの変更は、そのデータが Customers テーブルにのみ格納され、データベース内の他の場所に格納されていない場合に実装する方が簡単です。
"不整合な依存関係" とは ユーザーが顧客テーブルで特定の顧客の住所を確認するのは直感的ですが、その顧客を呼び出す従業員の給与を探しても意味がない場合があります。 従業員の給与は従業員に関連付けられているか依存しているため、従業員テーブルに移動する必要があります。 依存関係に一貫性がないと、データを見つけるパスが見つからないか壊れている可能性があるため、データへのアクセスが困難になる可能性があります。
データベースの正規化には、いくつかの規則があります。 各ルールは"標準フォーム" と呼ばれます。最初のルールが観察された場合、データベースは "最初の通常の形式" と言われます。最初の 3 つのルールが観察された場合、データベースは "3 番目の標準形式" と見なされます。他のレベルの正規化も可能ですが、3 番目の正規形式は、ほとんどのアプリケーションに必要な最高レベルと見なされます。
多くの正式な規則や仕様と同様に、実際のシナリオでは、常に完全なコンプライアンスが可能とは限りません。 一般に、正規化には追加のテーブルが必要であり、一部のお客様は、この面倒を見つけます。 正規化の最初の 3 つの規則のいずれかに違反する場合は、冗長なデータや一貫性のない依存関係など、発生する可能性のある問題がアプリケーションで予測されていることを確認します。
次の説明には例が含まれます。
最初の標準フォーム
- 個々のテーブル内の繰り返しグループを排除します。
- 関連データのセットごとに個別のテーブルを作成します。
- 関連データの各セットを主キーで識別します。
同じようなデータを格納するために、1 つのテーブルに複数のフィールドを使用しないでください。 たとえば、2 つの可能なソースからの在庫品目を追跡するために、在庫レコードに仕入先コード 1 と仕入先コード 2 のフィールドを含めることができます。
第 3 ベンダーを追加するとどうなりますか? フィールドを追加することは答えではありません。プログラムとテーブルの変更が必要であり、動的なベンダー数にスムーズに対応することはできません。 代わりに、仕入先と呼ばれる別のテーブルにすべての仕入先情報を配置し、品目番号キーを持つ仕入先に在庫をリンクするか、仕入先を仕入先コード キーを使用して在庫にリンクします。
2 番目の標準形式
- 複数のレコードに適用される値のセット用に個別のテーブルを作成します。
- これらのテーブルを外部キーと関連付けます。
レコードは、テーブルの主キー (必要に応じて複合キー) 以外に依存しないようにする必要があります。 たとえば、会計システムの顧客の住所を考えてみましょう。 住所は、Customers テーブルだけでなく、Orders、Shipping、Invoices、Accounts Receivable、Collections テーブルにも必要です。 顧客の住所をこれらの各テーブルに個別のエントリとして格納する代わりに、Customers テーブルまたは別の Addresses テーブルに 1 つの場所に格納します。
第 3 正規形
- キーに依存しないフィールドを削除します。
そのレコードのキーの一部ではないレコード内の値は、テーブルに属していません。 一般に、フィールドのグループの内容がテーブル内の 1 つ以上のレコードに適用される場合は、それらのフィールドを別のテーブルに配置することを検討してください。
たとえば、従業員採用テーブルには、候補者の大学名と住所が含まれる場合があります。 しかし、あなたはグループ郵送のための大学の完全なリストが必要です。 大学の情報が候補テーブルに格納されている場合、現在の候補者がいない大学を一覧表示する方法はありません。 別の Universitys テーブルを作成し、大学コード キーを使用して Candidates テーブルにリンクします。
例外:理論的には望ましいが、3番目の正常な形態に従することは必ずしも実用的ではない。 Customers テーブルがあり、考えられるすべてのフィールド間の依存関係を排除する場合は、都市、郵便番号、営業担当者、顧客クラス、および複数のレコードで重複する可能性があるその他の要素に対して個別のテーブルを作成する必要があります。 理論上、正規化は追求する価値があります。 ただし、多くの小さなテーブルでは、パフォーマンスが低下したり、開いているファイルとメモリの容量を超えたりする可能性があります。
頻繁に変更されるデータにのみ、3 番目の標準フォームを適用する方が適している場合があります。 一部の依存フィールドが残っている場合は、いずれかのフィールドが変更されたときに、ユーザーにすべての関連フィールドの検証を要求するようにアプリケーションを設計します。
その他の正規化形式
第4正規形は、Boyce-Codd 正規形(BCNF)とも呼ばれ、第5正規形は存在するが、実用的な設計ではほとんど考慮されない。 これらの規則を無視すると、データベースの設計が完全ではない可能性がありますが、機能に影響を与えるべきではありません。
サンプル テーブルの正規化
これらの手順では、架空の学生テーブルを正規化するプロセスを示します。
正規化されていないテーブル:
学生# アドバイザー Adv-Room クラス1 クラス2 Class3 1022 ジョーンズ 412 101-07 143-01 159-02 4123 スミス 216 101-07 143-01 179-04 最初の標準形式: 繰り返しグループなし
テーブルには 2 つのディメンションのみを含める必要があります。 1 人の学生に複数のクラスがあるため、これらのクラスは別のテーブルに一覧表示する必要があります。 上記のレコードのフィールド Class1、Class2、Class3 は、設計上の問題を示しています。
スプレッドシートでは多くの場合、3 番目のディメンションが使用されますが、テーブルでは使用しないでください。 この問題を確認するもう 1 つの方法は、一対多リレーションシップを使用することです。一方の側と多くの側を同じテーブルに配置しないでください。 代わりに、次の例に示すように、繰り返しグループ (Class#) を削除して、最初の標準形式で別のテーブルを作成します。
学生# アドバイザー Adv-Room クラス# 1022 ジョーンズ 412 101-07 1022 ジョーンズ 412 143-01 1022 ジョーンズ 412 159-02 4123 スミス 216 101-07 4123 スミス 216 143-01 4123 スミス 216 179-04 2 つ目の通常の形式: 冗長なデータを排除する
上記の表の各 Student# 値の複数の Class# 値に注意してください。 Class# は Student# (主キー) に機能的に依存しないため、このリレーションシップは 2 番目の通常の形式ではありません。
次の表は、2 番目の標準形式を示しています。
学生:
学生# アドバイザー Adv-Room 1022 ジョーンズ 412 4123 スミス 216 登録:
学生# クラス# 1022 101-07 1022 143-01 1022 159-02 4123 101-07 4123 143-01 4123 179-04 3 番目の標準形式: キーに依存しないデータを排除する
最後の例では、Adv-Room (アドバイザーのオフィス番号) は、Advisor 属性に機能的に依存しています。 解決策は、次に示すように、その属性を Students テーブルから Faculty テーブルに移動することです。
学生:
学生# アドバイザー 1022 ジョーンズ 4123 スミス 学部:
名前 部屋 部 ジョーンズ 412 42 スミス 216 42