データの正規化

この記事での学習内容 ITパスポート 基本情報 応用情報

正規化の目的と手順,第1 正規化,第2 正規化,第3 正規化などを理解する。また,正規化の考え方に従った,具体的な設計案に対して更新容易性や性能面などから評価し,最適な設計を行うことを理解する。

用語例:完全関数従属,部分関数従属,推移関数従属

正規化

正規化とは、『一事実一箇所を目指して、テーブルの整合性を保ったまま、テーブルの冗長性を排除してデータを管理できるようにすること』です。具体的には、データベースを設計する際に、各項目の意味や関連性を保ちながら、表ができるだけ簡潔な形になるように分割していく作業を指します。

正規化を行うことで、検索の効率が良くなり、データベースの保守作業がしやすくなるなどの長所があります。

一方で、表の数が増え、管理の手間がかかる点、一連のまとまった情報を得るために複数の表をたどる必要があり、負荷がかかるといった短所もあります。

例えば、学生の科目履修に関する「学生コード、学生名、科目コード、科目名、履修年度、成績」という情報を、一つの表に記録したとします。

このままでは、同じ内容が繰り返し格納されてしまうので、格納効率の悪い、使いにくいデータベースになってしまいます。

このデータベースを整理して、より効率的で使いやすいものにするためには、正規化を行い、共通の主キーに従属する列ごとに幾つかの表に分割します。

一つの表を複数に分けるときは、列同士の関連性を失わせないために、参照される表の主キーをもう一方の表に外部キーとして持たせておきます。

正規化の手順

正規化を徹底する手順は、以下のような3つのステップへ区分されます。

第一正規化
繰り返される部分を別の表として分割する。
第二正規化
キーの一部に従属する部分を別の表として分割する。部分関数従属という状態をなくす処理。
第三正規化
キーに間接的に従属する部分を別の表として分割する。推移関数従属という状態をなくす処理。
関数従属

「属性集合Aが属性集合Bに関数従属する」とは、「属性集合Bの値を決めると属性集合Aの値が一意に決まる」という意味です。これを「B→A」と表します。関数従属は、表を分割する正規化の手順を進める判断材料です。

完全関数従属

完全関数従属とは、表を分解する必要のない状態であり、キーでない属性がキーに関数従属して、部分関数従属はないということです。

部分関数従属

部分関数従属とは、キーでない属性が一部のキーにも関数従属することです。この状態であれば、第二正規化をする余地があります。

先述の「科目履修」の例であれば、「科目履修」の主キーは「学生コード」と「科目コード」ですが、「学生名」は「学生コード」に従属し、「科目名」は「科目コード」に従属しています。それぞれ、主キーの一部に関数従属しているので、部分関数従属となっています。

推移関数従属

推移関数従属とは、「AがBに従属して、BがCに従属するので、AはCに間接的に従属する」「C→B→A」という状態です。「B→A」の部分を分解するように第三正規化をする余地があります。

正規化の手順(具体例)

具体的な例として、オンラインショップの商品購入履歴を表にしたものを正規化していきます。

1.非正規形

まずは、伝票のたぐいをそのまま表にした状態のものを作ります。この時点では、繰返し項目や導出項目(*)を表の中に含みます。

*導出項目
合計値や評価など、他の項目から計算や関数によって導き出せる項目のことで、基本的にデータベースに格納する必要はない項目。

2.第一正規化

第一正規化では、『繰返し項目の分離』、『導出項目の削除』という作業を行います。

繰返し項目は、『商品ID~金額』のフィールドであり、これらのフィールドを『注文明細』テーブルとして分割します。

さらに、『金額』、『合計金額』、『消費税』については、『単価』、『数量』をもとに算出できるので、削除します。

第一正規化を行った後の表は、以下のようになります。

3.第二正規化

第二正規化では、「部分関数従属」を別表に移す作業を行います。

『注文明細』テーブルのうち、『商品名』、『分類』、『単価』は、『商品ID』によって一意に決まるので、分割できます。

第二正規化を行った後の表は、下のようになります。

4.第三正規化

 第三正規化では、『推移関数従属』を別表に移す作業を行います。

『注文』テーブルのうち、『名前』、『住所』、『電話番号』、は、『顧客ID』によって一意に決まるので、分割できます。『顧客ID』は、『注文』テーブルの主キーではないため、このようなパターンを『推移関数従属』といいます。

第三正規化を行った後の表は、下のようになる。