正規化 とは
正規形とは、データベースで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式のことです。
正規形のレベルは第 5 までありますが、通常の業務で使用するレベルとして、第 3 正規形までを考えることが多いため、最初は第 3 正規形までを理解していれば十分です。
また、第 3 正規形まで達成したら、その時点で以降の正規形の条件も満たしていることがほとんどです。
非正規形
非正規形の定義は、「1 つのセルに対して複数の値が含まれてしまっている状態」です。(上記の例でいうと「社員 ID」以降すべて)
これには、主キーが各列の値を一意に決定できないという問題があります。
第 1 正規形
非正規形の問題を解消するには、1 つのセルに対して複数の値が含まれてしまっているセルを下記のように複数のレコードに分割して上げる必要があります。
これを第 1 正規化と呼びます。
第 1 正規形の定義は、「テーブル内のすべてのセルが単一の値のみを保持している状態」です。
この第 1 正規形にはまだ問題があります。
それは、社員の情報が不明の会社(C 建設)があった場合、主キーの一部に社員 ID が含まれているため、これが不明の状態ではレコードを登録できないということです。
また、会社コードと会社名の対応がレコードによってマチマチになってしまう危険があることです。例えば、{C0001, A 商事}というレコードの他に、{C0001, A 商社}というデータが登録されてしまうなど…
第 2 正規形
さらに第 1 正規形の問題を解決する必要があるのですが、ここで正規形全体を理解するために重要な概念を説明します。
それが関数従属性です。これは「X 列の値決めれば、Y 列の値が一意に決定する関係」のことを表し、{X} → {Y}
のように表現します。
次に、 第 1 正規形 を見ると、このテーブルの主キーは {会社コード, 社員 ID} ですが、「会社名」列だけは、主キーの一部である「会社コード」に従属しており、{会社コード} → {会社名}
のような関数従属性があります。
このように、主キーの一部の列に対して従属する列がある場合の関係性のことを部分関数従属と呼びます。それに対して、主キーを構成するすべての列に対して従属する列がある場合の関係性のことを完全関数従属と呼びます。
テーブルを複数に分割することで部分関数従属を解消し、完全関数従属のみになっている状態を作るのを第 2 正規化と呼びます。つまり、第 2 正規形の定義は、「テーブルが完全関数従属のみになっている(複合主キーを持つ場合に、非キー属性がその主キーの一部にだけ依存しない)状態」です。
この第 2 正規形にもまだ問題があります。
それは、社員が一人もいない部署があった場合、主キーの一部に社員 ID が含まれているため、レコードを登録できないということです。
第 3 正規形
第 2 正規形について、「部署コード」と「部署名」の 2 列の間には、{部署コード} → {部署名}
という関数従属が成立する一方、「社員 ID」と「部署コード」の間にも{会社コード, 社員ID} → {部署コード}
という関数従属が存在しています。つまり、全体としては{会社コード, 社員ID} → {部署コード} → {部署名}
という二段階の関数従属性が存在します。このような従属関係のことを 推移的関数従属 と呼びます。
これを第 2 正規化のときと同じようにテーブル分割し、それぞれの関数従属の関係を独立させます。
よって第 3 正規形の定義は、「推移的関数従属が解消され、非キー列はキー列に対してのみ従属する状態」です。
まとめ
- 実務においては、第 3 正規形まで行うべき
- 非正規形の定義は、1 つのセルに対して、複数の値が含まれている状態
- 第 1 正規形の定義は、テーブル内のすべてのセルが単一の値のみを保持している状態
- 第 2 正規形の定義は、複合主キーを持つ場合に、非キー属性がその主キーの一部にだけ依存しない状態(主キーが 1 つの場合は自然と第 2 正規形の条件を満たす)
- 第 3 正規形の定義は、非キー列はキー列に対してのみ従属する状態
参考書籍