database正規化の流れを1分で確認しよう

#**はじめに**
アプリケーションを実際に作成し始める前には必要なデータを洗い出し、データベース設計をするのが大切になってきますよね。今回は、リレーショナルデータベース（RDB: Relational Database）を正規化していきたいと思います。流れを整理するために簡単なモデルを扱い自分用のメモとして投稿します。

#**非正規形と正規形**
正規化の目的は、データに矛盾や重複を生じさせないことです。関係データベース（RDB）では、第３正規形の票を管理します。
では、それぞれの段階ごとの意味を簡単に確認していきます。

####**非正規形**
正規化されていない繰り返し部分を持つ表

####**第1正規形**
繰り返し部分を分散させて、独立したレコードとした表

####**第2正規形**
部分関数従属している列を切り出したかたちの表

####**第３正規形**
主キー以外の列に関数従属している列を切り出したかたちの表

#**正規化しよう**

では、業務で使われている帳票上のデータをデータベースで管理することを考えてみます。
帳票一枚が一件のレコードに相当するとしたら、まずは、次のようなデータベースの構成になります。


| 受注No | 受注日付 | 顧客コード | 顧客名称 | 商品コード | 商品名 | 単価 | 数量 | 金額 | 商品コード | 商品名 | 単価 | 数量　| 金額 |
|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|
| 1011  | 2017/07/01  | c010  | aaa出版  | B107  | 紙ファイル  | 50  |  12 | 600  | B120  | 3色ボールペン  | 300  | 8  | 2400 |
| 1103  | 2017/07/13  | c021  | bbb工業  | B113  | ハサミ  | １98  | 10  | 1,980  |  |  |  |  |  |

ただし、こちらは非正規形になります。

##**第1正規形**
非正規形の表から、繰り返しの部分を取り除いたものが第1正規形となります。
計算で求められる「金額」の列は、いちいち記録する必要がないので取っ払います。

| 受注No | 受注日付 | 顧客コード | 顧客名称 | 商品コード | 商品名 | 単価 | 数量 |
|:--|:--|:--|:--|:--|:--|:--|:--|
| 1011  | 2017/07/01  | c010  | aaa出版  | B107  | 紙ファイル  | 50  |  12 |
| 1011  | 2017/07/01  | c010  | aaa出版  | B120  | 3色ボールペン  | 300  | 8  |
| 1103  | 2017/07/13  | c021  | bbb工業  | B113  | ハサミ  | 198  | 10|

１行目のレコードが二つに分割されました。この際、「受付No」〜「顧客名称」の情報が補われて独立したレコードができています。

##**第2正規形**

第1正規系の表から、部分関数従属している列を取り出したものが第2正規系となります。

ここで、関数従属と部分関数従属の意味を下記に記しておきます。

###**関数従属とは**
主キーが決まれば、列の値が一意に定まる関係
例えば

| 社員番号 | 名前 | 部署 |
|:--|:--|:--|
| 2017001  | 古川拓也  | 開発部  |
| 1017002  | 上浦佳子  | 営業部  |

といったテーブルがある時、社員番号（主キー）が決まると「名前」「部署」が決まります。
このような関係を関係従属と呼びます。
「名前」は「社員番号」に関数従属している、などと使います。

###**部分関数従属とは**
主キー（複合キー）の一部の項目だけで、列の値が一意に定まる関係
例えば

| 受注No | 受注日付 | 顧客コード | 顧客名称 | 商品コード | 商品名 | 単価 | 数量 |
|:--|:--|:--|:--|:--|:--|:--|:--|
| 1011  | 2017/07/01  | c010  | aaa出版  | B107  | 紙ファイル  | 50  |  12 |
| 1011  | 2017/07/01  | c010  | aaa出版  | B120  | 3色ボールペン  | 300  | 8  |

といったテーブルがあるとき、
「受付No」が決まれば、受付日時」「顧客コード」「顧客名称」が決まり、
「商品コード」が決まれば、「商品名」「単価」が決まります。
このような関係を部分関係従属と呼びます。

では、語句の意味を抑えたところで、第2正規系にするとが次の３つの表に分けられます。
語句の意味がわかっていれば悩むことはないですね。

<caption>**受注表**</caption>

| 受注No | 受注日付 | 顧客コード | 顧客名称 |
|:--|:--|:--|:--|
| 1011  | 2017/07/01  | c010  | aaa出版  |
| 1011  | 2017/07/01  | c010  | aaa出版  |
| 1103  | 2017/07/13  | c021  | bbb工業  |

<caption>**商品表**</caption>

| 商品コード | 商品名 | 単価 |
|:--|:--|:--|
| B107  | 紙ファイル  | 50  |
| B120  | 3色ボールペン  | 300  |
| B113  | ハサミ  | 198 |

<caption>**受注明細表**</caption>

| 受注No | 商品コード |　数量　|
|:--|:--|:--|
| 1011 | B107 | 12|
| 1011 | B120 | 8|
| 1103 | B113 | 10|


##**第３正規系**

最後に第３正規系ですね。
主キー以外の列に関数従属している列を切り出したものが第３正規系になります。
先ほど作成した受注表では、「顧客名称」は主キーの「受注No」ではなくて、「顧客コード」をキーとして決定されます。
というわけで、分散させると次のようになります。

<caption>**受注表**</caption>

| 受注No | 受注日付 | 顧客コード |
|:--|:--|:--|:--|
| 1011  | 2017/07/01  | c010  | 
| 1011  | 2017/07/01  | c010  | 
| 1103  | 2017/07/13  | c021  |

<caption>**顧客表**</caption>



| 顧客コード | 顧客名称 |
| :-- | :-- |
| c010  | aaa出版  |
| c010  | aaa出版  |
| c021  | bbb工業  |

<caption>**商品表**</caption>

| 商品コード | 商品名 | 単価 |
|:--|:--|:--|
| B107  | 紙ファイル  | 50  |
| B120  | 3色ボールペン  | 300  |
| B113  | ハサミ  | 198 |

<caption>**受注明細表**</caption>

| 受注No | 商品コード |　数量　|
|:--|:--|:--|
| 1011 | B107 | 12|
| 1011 | B120 | 8|
| 1103 | B113 | 10|


これで、第3正規化が完了しました。

#**終わりに**
正規化の流れを復習しました。
データベースをしっかりと設計し、アプリ制作にとりかかりたいと思います。