データベース正規化の基本の説明

注意

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

元の KB 番号:   283878

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

正規化の説明

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

冗長なデータはディスク領域を無駄にし、メンテナンスの問題を引き起します。 複数の場所に存在するデータを変更する必要がある場合は、すべての場所でまったく同じ方法でデータを変更する必要があります。 顧客アドレスの変更は、そのデータが Customers テーブルにのみ格納され、データベース内の他の場所に格納されている場合に実装がはるかに簡単です。

"一貫性のない依存関係" とは何ですか? ユーザーが特定の顧客の住所を [顧客] テーブルで見るのは直感的ですが、その顧客を呼び出す従業員の給与を探すのは意味がない場合があります。 従業員の給与は従業員に関連付け、または従業員に依存するため、Employees テーブルに移動する必要があります。 依存関係が矛盾すると、データを見つけるパスが見つからないか壊れている可能性があります。データへのアクセスが困難になる可能性があります。

データベースの正規化にはいくつかのルールがあります。 各ルールは"標準フォーム" と呼ばれる。 最初のルールが観察された場合、データベースは "最初の通常の形式" と言います。 最初の 3 つのルールが観察された場合、データベースは "3 番目の通常の形式" であると見なされます。 他のレベルの正規化が可能ですが、3 番目の標準フォームは、ほとんどのアプリケーションに必要な最高レベルと見なされます。

多くの正式なルールや仕様と同様に、実際のシナリオでは必ずしも完全なコンプライアンスが許可されるとは限りしません。 一般に、正規化には追加のテーブルが必要であり、一部のお客様は、この作業が面倒です。 正規化の最初の 3 つのルールの 1 に違反する場合は、冗長なデータや一貫性のない依存関係など、発生する可能性のある問題がアプリケーションで予測されます。

次の説明には、例が含まれます。

最初の標準フォーム

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

同様のデータを格納するには、1 つのテーブルで複数のフィールドを使用しない。 たとえば、2 つのソースから取得できる在庫アイテムを追跡するには、仕入先コード 1 と仕入先コード 2 のフィールドがインベントリ レコードに含まれる場合があります。

3 番目のベンダーを追加すると何が起こりますか? フィールドの追加は答えではありません。プログラムとテーブルの変更が必要であり、動的な数のベンダーにスムーズに対応できません。 代わりに、すべてのベンダー情報を Vendors という別のテーブルに配置し、アイテム番号キーを持つ仕入先に在庫をリンクするか、ベンダーを仕入先コード キーでインベントリにリンクします。

2 番目の標準フォーム

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

レコードは、テーブルの主キー (必要に応じて複合キー) 以外に依存する必要はありません。 たとえば、会計システムで顧客の住所を考え出します。 このアドレスは、Customers テーブルだけでなく、Orders、Shipping、Invoices、Accounts Receivable、および Collections テーブルによっても必要です。 これらの各テーブルに顧客の住所を個別のエントリとして格納する代わりに、顧客テーブルまたは別の Address テーブルの 1 か所に保存します。

3 番目の標準フォーム

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

そのレコードのキーの一部ではないレコード内の値は、テーブルに属していない。 一般に、フィールドのグループの内容がテーブル内の 1 つ以上のレコードに適用される場合は、それらのフィールドを別のテーブルに配置する必要があります。

たとえば、従業員募集テーブルに、候補者の大学名と住所を含めできます。 ただし、グループメール用の大学の完全なリストが必要です。 大学情報が [候補] テーブルに格納されている場合は、現在の候補者がない大学を一覧表示する方法はありません。 別の Universitys テーブルを作成し、大学コード キーを使用して Candidates テーブルにリンクします。

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

頻繁に変更されるデータにのみ、3 番目の通常のフォームを適用する方が実現可能な場合があります。 一部の依存フィールドが残っている場合は、変更時に関連するフィールドをユーザーに確認する必要があるアプリケーションを設計します。

その他の正規化フォーム

4 番目の通常のフォーム (Boyce Codd Normal Form (BCNF) とも呼ばれる)、および 5 番目の標準フォームは存在しますが、実用的な設計ではほとんど考慮されません。 これらのルールを無視すると、完全なデータベース設計よりも小さい場合がありますが、機能に影響を与える必要があります。

テーブルの例の正規化

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

  1. 正規化されていないテーブル:

    学生# Advisor Adv-Room Class1 Class2 Class3
    1022 Jones 412 101-07 143-01 159-02
    4123 Smith 216 101-07 143-01 179-04
  2. 最初の通常のフォーム: 繰り返しグループなし

    テーブルのサイズは 2 つのみです。 1 人の学生に複数のクラスが含まれていますので、これらのクラスは別のテーブルに一覧表示する必要があります。 上記のレコードのフィールド Class1、Class2、Class3 は、設計上の問題を示しています。

    多くの場合、スプレッドシートは 3 番目のディメンションを使用しますが、テーブルは使用できません。 この問題を見るもう 1 つの方法は、1 対多の関係で、一方の側と多側を同じテーブルに入れない方法です。 代わりに、次に示すように、繰り返しグループ (Class#) を削除して、最初の通常の形式で別のテーブルを作成します。

    学生# Advisor Adv-Room クラス#
    1022 Jones 412 101-07
    1022 Jones 412 143-01
    1022 Jones 412 159-02
    4123 Smith 216 101-07
    4123 Smith 216 143-01
    4123 Smith 216 179-04
  3. 2 番目の通常の形式: 冗長なデータを排除する

    上記の表の各 Student# 値の複数の Class# 値に注意してください。 Class# は Student# (主キー) に機能的に依存しないので、この関係は 2 番目の通常の形式ではありません。

    次の表は、2 番目の通常の形式を示しています。

    学生:

    学生# Advisor Adv-Room
    1022 Jones 412
    4123 Smith 216

    登録:

    学生# クラス#
    1022 101-07
    1022 143-01
    1022 159-02
    4123 101-07
    4123 143-01
    4123 179-04
  4. 3 番目の通常のフォーム: キーに依存しないデータを削除する

    最後の例では、Adv-Room (アドバイザーのオフィス番号) は、Advisor 属性に機能的に依存します。 解決策は、次に示すように、その属性を Students テーブルから Faculty テーブルに移動します。

    学生:

    学生# Advisor
    1022 Jones
    4123 Smith

    教員:

    Name Room
    Jones 412 42
    Smith 216 42