データベース正規化の基本事項について

注意

Office 365 用リソース は、 エンタープライズ向け Microsoft 365 アプリに名前変更されています。 この変更の詳細については、 このブログの投稿を参照してください。

元の KB 番号:  283878

この記事では、初心者向けのデータベース正規化の用語について説明します。 この用語に関する基本的な理解は、リレーショナルデータベースの設計について話し合う際に役立ちます。

正規化の説明

正規化とは、データベース内のデータを整理するプロセスのことです。 これには、データを保護するために設計されたルールに従ってテーブルを作成し、それらのテーブル間のリレーションシップを確立することと、冗長性と一貫性のない依存関係を排除することで、データベースの柔軟性を高めることが含まれます。

冗長データはディスク領域を浪費し、メンテナンスの問題を発生させる。 複数の場所に存在するデータを変更する必要がある場合は、すべての場所で同じ方法でデータを変更する必要があります。 顧客住所の変更は、そのデータが Customers テーブルのみに格納され、データベース内の他の場所に保存されていないと、より簡単に実装できます。

"不整合な依存関係" とは ユーザーが特定の顧客の住所を [顧客] テーブルで確認するのは直観的ですが、その顧客に電話をかけている従業員の給与を確認することは適切ではありません。 従業員の給与は、従業員に関連付けられているか、従業員に依存しているため、Employees テーブルに移動する必要があります。 依存関係の不整合は、データを見つけるためのパスが欠落しているか破損しているため、データへのアクセスが困難になる可能性があります。

データベースの正規化には、いくつかのルールがあります。 各ルールは "標準形式" と呼ばれます。 最初のルールが守られている場合、データベースは "最初の標準のフォーム" にあると見なされます。 最初の3つのルールが守られている場合、データベースは "第3正規形" と見なされます。 他のレベルの正規化も可能ですが、第3の標準形式は、ほとんどのアプリケーションで必要とされる最上位のレベルです。

多くの正式なルールおよび仕様と同様に、実際のシナリオでは、完全なコンプライアンスを常に許可するわけではありません。 一般に、正規化には追加のテーブルが必要で、一部のお客様はこの煩雑な結果を感じます。 正規化の最初の3つのルールのうちの1つに違反している場合は、冗長データや矛盾した依存関係など、アプリケーションで問題が発生していることを確認してください。

次の説明に例を示します。

最初の標準形式

  • 個々のテーブル内の繰り返しグループを除去します。
  • 関連するデータのセットごとに個別のテーブルを作成します。
  • 関連するデータのセットを主キーで識別します。

類似したデータを格納するために、1つのテーブルで複数のフィールドを使用しないでください。 たとえば、2つのソースからの在庫品目を追跡する場合、在庫レコードにはベンダーコード1とベンダーコード2のフィールドが含まれていることがあります。

3番目のベンダーを追加するとどうなりますか。 フィールドを追加することは、答えではありません。プログラムおよびテーブルを変更する必要があり、動的なベンダーの数にスムーズに対応することはできません。 代わりに、すべてのベンダー情報をベンダーという別のテーブルに配置し、品目番号キーを使用してベンダーに在庫をリンクするか、ベンダーコードキーを使用して在庫を inventory にリンクします。

2番目の標準フォーム

  • 複数のレコードに適用する値のセットに対して個別のテーブルを作成します。
  • これらのテーブルと外部キーを関連付けます。

レコードは、テーブルの主キー (必要な場合は複合キー) 以外に依存しないようにしてください。 たとえば、会計システムの顧客の住所を考えてみます。 住所は Customers テーブルで必要ですが、Orders、送料、請求書、売掛金、およびコレクションの各テーブルでも必要です。 これらの各テーブルには、顧客の住所を個別のエントリとして格納するのではなく、Customers テーブルまたは別の住所の表のいずれかの場所に格納します。

第3正規形

  • キーに依存しないフィールドを削除します。

そのレコードのキーに含まれていないレコード内の値は、テーブルには含まれません。 通常、フィールドグループの内容がテーブル内の複数のレコードに適用される場合は、それらのフィールドを別のテーブルに配置することを検討してください。

たとえば、従業員採用表では、応募者の大学の名前と住所を含めることができます。 ただし、グループメールの場合は、完全な大学の一覧が必要です。 大学の情報が求職者の表に格納されている場合は、現在の応募者がいない大学をリストすることはできません。 別の学問所の表を作成し、それを大学のコードキーを使用して、求職者の表にリンクします。

例外: 3 番目の標準形式に準拠していますが、理論上望ましいのは常に現実的ではありません。 Customers テーブルがあり、すべての使用可能なフィールド間の依存関係を削除する場合は、都市、郵便番号、販売担当者、顧客クラス、および複数のレコードで重複する可能性があるその他の要因に対して個別のテーブルを作成する必要があります。 理論的には、正規化を行う価値があります。 ただし、多くの小さなテーブルでは、パフォーマンスが低下したり、開いているファイルとメモリ容量を超えたりすることがあります。

第3正規形を、頻繁に変更されるデータにのみ適用する方がより現実的な場合があります。 一部の依存フィールドが残っている場合は、いずれかが変更されたときに、ユーザーがすべての関連フィールドを確認するようにアプリケーションを設計します。

その他の正規化形式

4番目の標準フォーム (Boyce Codd 標準形式 (BCNF)、および5番目の標準形式) は存在しますが、実際の設計ではほとんど考慮されません。 これらのルールを無視すると、完全なデータベース設計よりも小さくなる可能性がありますが、機能に影響を与えることはありません。

テーブルの例を正規化する

次の手順では、架空の学生テーブルを正規化するプロセスについて説明します。

  1. 正規化していない表:

    学生# Adv-ルーム Class1 Class2 Class3
    1022 Jones 412 101-07 143-01 159-02
    4123 鈴木 216 201-01 211-02 214-01
  2. 最初の標準形式: 繰り返しグループはありません

    テーブルには2つの次元しかありません。 1人の学生は複数のクラスを持っているため、これらのクラスは別の表に記載する必要があります。 上記のレコードの Class1、Class2、および Class3 のフィールドには、設計の問題が示されています。

    スプレッドシートでは、3番目の次元がよく使用されますが、テーブルは使用しないでください。 この問題を確認するもう1つの方法は、一対多のリレーションシップの場合、1つのテーブル内に1側と複数の面を配置しないことです。 代わりに、次に示すように、繰り返しグループ (クラス #) を削除して、最初の標準形式で別のテーブルを作成します。

    学生# Adv-ルーム クラス#
    1022 Jones 412 101-07
    1022 Jones 412 143-01
    1022 Jones 412 159-02
    4123 鈴木 216 201-01
    4123 鈴木 216 211-02
    4123 鈴木 216 214-01
  3. 第2正規形: 冗長データを排除する

    上記の表の各 Student # 値について、複数のクラス # の値をメモしておきます。 クラス # は、生徒番号 (主キー) に対して機能的に依存していないため、この関係は2番目の標準形式ではありません。

    2番目の標準形式の表を次に示します。

    説明

    学生# Adv-ルーム
    1022 Jones 412
    4123 鈴木 216

    レジスタ

    学生# クラス#
    1022 101-07
    1022 143-01
    1022 159-02
    4123 201-01
    4123 211-02
    4123 214-01
  4. 第3正規形: キーに依存しないデータを除外する

    最後の例では、Adv (アドバイザーのオフィス番号) は、アドバイザー属性によって機能的に依存しています。 このソリューションでは、次のように、その属性を Student テーブルから教職員テーブルに移動します。

    説明

    学生#
    1022 Jones
    4123 鈴木

    教職員

    名前 Room Dept
    Jones 412 42
    鈴木 216 42