はじめに
この記事では、Accessなどのデータベース管理ソフトにおいて重要な正規化について説明します。
正規化とは
データベースにおける正規化とは、データベース設計においてデータの冗長性を減らし、データの整合性を保つための方法です。ここで、
- データの冗長性の排除とは、データの重複を排除すること
- データの整合性とは、データの正確性、完全性(必要な情報が揃っていること)、一貫性(データが論理的に矛盾していないこと)を保証すること
を意味します。データの冗長性とデータの整合性については、下の具体例でまた詳しく説明します。
テーブルを正規形にすることで、データの更新や集計等の管理が効率的になります。
正規化の具体例
正規化には、第一正規化、第二正規化、第三正規化があります。以下では、注文管理テーブルを例に非正規形のテーブルから正規化をしていく手順を紹介します。
1. 非正規形のテーブル
下図のように注文を管理するテーブルを用意しました。
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A 商品B |
2 4 |
1500 200 |
2 | B会社 | 神奈川県 | 2025/7/1 | 商品B | 3 | 200 |
3 | A会社 | 東京都 | 2025/7/2 | 商品C | 2 | 400 |
4 | B会社 | 神奈川県 | 2025/7/2 | 商品A,商品C | 1,5 | 1500,400 |
このようなテーブルを次のようなフローで正規化します。
上の注文管理テーブルでは次のような特徴があります。
注文番号1と3のデータを見ると、同じ顧客が注文しており、その顧客情報(顧客名、住所)が繰り返されていることが分かります。データの冗長性とは、このような顧客情報の重複のことをいい、余分なデータを保存するため、不必要にディスク容量を圧迫します。
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A 商品B |
2 4 |
1500 200 |
3 | A会社 | 東京都 | 2025/7/2 | 商品C | 2 | 400 |
またデータの冗長性により、次のようなデメリットもあります。
例2のようにA会社の住所を修正する場合、顧客名がA会社の注文データの住所全てを変更しなければならなくなります。またこのとき、変更し忘れたデータや間違えて変更したデータが有ると、データの正確性が失われる、つまりデータの整合性が失われます。
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 千葉県 | 2025/7/1 | 商品A 商品B |
2 4 |
1500 200 |
3 | A会社 | 千葉県 | 2025/7/2 | 商品C | 2 | 400 |
以下では正規化によって、このようなデメリットを解消します。
データの整合性で説明した完全性は、フィールドの値を必須にすることによって、一貫性は参照整合性を設定すること等によって、保証することが出来ます。
2. 第一正規化
第一正規化とは、各項目(フィールドまたはセル)に単一の値だけが含まれるようにします。
非正規形の注文管理テーブルでは、注文番号1と4のデータを見ると、商品名などの項目に複数の値が含まれています。第一正規化によって、商品名など各項目に値が一つだけしか含まれない形にします。
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A 商品B |
2 4 |
1500 200 |
4 | B会社 | 神奈川県 | 2025/7/2 | 商品A,商品C | 1,5 | 1500,400 |
第一正規化を行うと、注文管理テーブルは次のようになります。
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A | 2 | 1500 |
1 | A会社 | 東京都 | 2025/7/1 | 商品B | 4 | 200 |
2 | B会社 | 神奈川県 | 2025/7/1 | 商品B | 3 | 200 |
3 | A会社 | 東京都 | 2025/7/2 | 商品C | 2 | 400 |
4 | B会社 | 神奈川県 | 2025/7/2 | 商品A | 1 | 1500 |
4 | B会社 | 神奈川県 | 2025/7/2 | 商品C | 5 | 400 |
3. 第二正規化
第二正規化とは、主キーと呼ばれる項目に依存する項目がないように別のテーブルに分割します。ここで主キーとは、データ(行)を一意に識別するための項目(またはその組み合わせ)を意味します。
分かりやすく言い換えると、主キーは、ある項目の値をなにか指定すると、データ(行)を一つに特定できるような項目(またはその組み合わせ)です。
注文管理テーブルの例では、注文番号と商品名の項目をそれぞれ一つ指定するとデータ(行)を一つに特定することができて、注文日や数量など他の項目を知ることが出来ます。
例えば、
- 注文番号1を指定すると得られるデータは二つ(二行) => 注文番号だけではデータを一つに特定できない
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A | 2 | 1500 |
1 | A会社 | 東京都 | 2025/7/1 | 商品B | 4 | 200 |
- 商品名で商品Aを指定すると得られるデータは二つ(二行) => 商品名だけではデータを一つに特定できない
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A | 2 | 1500 |
4 | B会社 | 神奈川県 | 2025/7/2 | 商品A | 1 | 1500 |
- 注文番号は1、商品名は商品Aを指定 => データを一つに特定可能
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A | 2 | 1500 |
したがって、注文番号と商品名が連結主キーと呼ばれる主キーとなっています。
また、第二正規化を分かりやすく説明しなおすと、主キーのうちの一つについてどんな値を決めても、値を一つに特定できるような項目(主キー以外の項目)をもとのテーブルから別のテーブルに切り離すことです
具体的には、注文管理テーブルをみると、主キーのうちの注文番号を一つ指定することで、顧客名、住所、注文日の項目を特定できることが分かります。よって、顧客名と住所は注文番号に依存していることがわかります。
同様に、単価(円)の項目も商品名に依存していることがわかります。
注文番号 | 顧客名 | 住所 | 注文日 | 商品名 | 数量 | 単価(円) |
---|---|---|---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 | 商品A | 2 | 1500 |
1 | A会社 | 東京都 | 2025/7/1 | 商品B | 4 | 200 |
2 | B会社 | 神奈川県 | 2025/7/1 | 商品B | 3 | 200 |
3 | A会社 | 東京都 | 2025/7/2 | 商品C | 2 | 400 |
4 | B会社 | 神奈川県 | 2025/7/2 | 商品A | 1 | 1500 |
4 | B会社 | 神奈川県 | 2025/7/2 | 商品C | 5 | 400 |
以上のことから、第一正規化後の注文管理テーブルから顧客名、住所、注文日、単価(円)の項目がなくなるように、注文管理テーブル、商品管理テーブル、注文顧客管理テーブルに分割します。
注文番号 | 商品名 | 数量 |
---|---|---|
1 | 商品A | 2 |
1 | 商品B | 4 |
2 | 商品B | 3 |
3 | 商品C | 2 |
4 | 商品A | 1 |
4 | 商品C | 5 |
商品名 | 単価(円) |
---|---|
商品A | 1500 |
商品B | 200 |
商品C | 400 |
注文番号 | 顧客名 | 住所 | 注文日 |
---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 |
2 | B会社 | 神奈川県 | 2025/7/1 |
3 | A会社 | 東京都 | 2025/7/2 |
4 | B会社 | 神奈川県 | 2025/7/2 |
4. 第三正規化
第三正規化とは、主キー以外の項目に依存する項目をそのテーブルからなくなるように別テーブルに分離します。
注文顧客管理テーブルの主キーは注文番号ですが、主キーでない項目(顧客名)を指定すると、住所が特定できます。例えば顧客名の値をA会社に指定すると、住所は東京都に特定することが出来ます。つまり、住所が顧客名に依存していることが分かります。
注文番号(主キー) | 顧客名 | 住所 | 注文日 |
---|---|---|---|
1 | A会社 | 東京都 | 2025/7/1 |
2 | B会社 | 神奈川県 | 2025/7/1 |
3 | A会社 | 東京都 | 2025/7/2 |
4 | B会社 | 神奈川県 | 2025/7/2 |
よって、注文顧客管理テーブルから住所の項目がなくなるように、注文顧客管理テーブルと顧客管理テーブルに分割することが出来ます。
注文番号 | 顧客名 | 注文日 |
---|---|---|
1 | A会社 | 2025/7/1 |
2 | B会社 | 2025/7/1 |
3 | A会社 | 2025/7/2 |
4 | B会社 | 2025/7/2 |
顧客名 | 住所 |
---|---|
A会社 | 東京都 |
B会社 | 神奈川県 |
以上のように正規化することによって、データの更新や管理が効率的になります。
例えば、A会社の住所を変更したい場合、顧客管理テーブルのA会社のデータ(行)を変更するだけで済むようになります。
また、正規化されたテーブルでは、各項目に一つの値だけが含まれているので、
- 商品名の項目には複数の値が含まれているのに数量の項目には一つの値しか含まれていない
といったデータの欠落を防ぐことが出来ます。
正規化はデータの更新や管理が効率的になりますが、場合によっては、あえてデータに冗長性をもたせること(データの重複を許すということ)等が有用であるため、必ずしも正規化すればよいというわけではありません。
最後に、もう一度正規化までのフローを確認すると次のようになります。
まとめ
- 正規化とは、データの冗長性を減らし、データの整合性を保つ手法
- 正規化には、第一正規化、第二正規化、第三正規化が存在
- 正規化によって、データの管理や分析が効率化
参照
武藤 玄「ACCESS VBA ベーシック」
What Is Data Integrity?
Introduction to Database Normalization