テーブル正規化に関してまとめてみた

<h1>データベースの正規化</h1>
PMに「正規化わかります〜？」って言われて「？？？」となったので調べてまとめてみた。




<h2>正規化とは🌀</h2>
Wikipediaさん曰く、<br>
<a href="https://ja.wikipedia.org/wiki/%E9%96%A2%E4%BF%82%E3%81%AE%E6%AD%A3%E8%A6%8F%E5%8C%96">
「関係（リレーション）を正規形と呼ばれる形式に準拠させることにより、データの一貫性の維持と効率的なデータアクセスを可能にする関係設計を導くための方法である。」
</a>
だそうです。
<br>
<br>
言っている意味はなんとなくわかるけど、なんかシックリこないな・・・
<br>
自分はざっくり、こう解釈しました。
<br>
<p><b>テーブルを各項目(会社ごと、社員ごと、チームごと)に分けることで、データ管理しやすくなる。</b></p>

例を示します。こんなテーブルがあったとします。
<h4>■会社社員情報マスタ</h4>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
        <td>社員ID</td>
        <td>社員名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>社員A</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0002</td>
        <td>社員B</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0003</td>
        <td>社員C</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
        <td>0004</td>
        <td>社員D</td>
    </tr>
</table>
BPの社員Dさんが辞めた場合、会社ID=0002、社員ID=0004のレコードは削除されます。
<br>
これだと社員IDだけでなく会社IDも消えます。
<br>
会社情報は残しておいても問題なさそうですよね。
では、会社情報切り出してみます。
<br>
これなら社員Dさんが辞めても会社情報は消えません。
<h4>■会社マスタ</h4>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
    </tr>
</table>
<h4>■社員マスタ</h4>
<table>
    <tr>
        <td>社員ID</td>
        <td>社員名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>社員A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>社員B</td>
    </tr>
    <tr>
        <td>0003</td>
        <td>社員C</td>
    </tr>
    <tr>
        <td>0004</td>
        <td>社員D</td>
    </tr>
</table>
これが正規化と呼ばれるものだそうです。🍺





<h2>第一正規系🌀</h2>
テーブルに格納できる状態に整理します。
<br>
社員Aさんが沢山のチームに所属していたとします。
<br>
<h4>■第一正規化前</h4>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
        <td>社員ID</td>
        <td>社員名</td>
        <td>チームID</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0001<br>0002<br>0003</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0002</td>
        <td>社員B</td>
        <td>0001</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0003</td>
        <td>社員C</td>
        <td>0001</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>シアトル</td>
        <td>0004</td>
        <td>社員D</td>
        <td>0001</td>
    </tr>
</table>
リレーショナルデータベースにおいて、一つのセルには一つの値しか入ってはいけないので、これだとデータをマスタに登録できません。
なので、以下の形に修正します。

<h4>■第一正規化後</h4>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
        <td>社員ID</td>
        <td>社員名</td>
        <td>チームID</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0001</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0002</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0003</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0002</td>
        <td>社員B</td>
        <td>0001</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0003</td>
        <td>社員C</td>
        <td>0001</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>シアトル</td>
        <td>0004</td>
        <td>社員D</td>
        <td>0001</td>
    </tr>
</table>
これが第一正規系と呼ばれるものです。🍺




<h2>第二正規系🌀</h2>
「テーブルの各候補キーに従属する部分関数従属性が整理された状態」
<br>
候補キーはレコードを一意に特定するための属性（＝カラム）のこと。要は主キーみたいなもんだと思っています。
<br>
部分従属とは、Xが決まるとYが決まる関係のことです。X→Yとかって書いたりします。
<br>
<h4>■第二正規化前</h4>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
        <td>部署ID</td>
        <td>部署名</td>
        <td>社員ID</td>
        <td>社員名</td>
        <td>チームID</td>
        <td>チーム名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0002</td>
        <td>B</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0003</td>
        <td>C</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0002</td>
        <td>社員B</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0003</td>
        <td>社員C</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
        <td>0002</td>
        <td>コーポレート</td>
        <td>0004</td>
        <td>社員D</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
        <td>0002</td>
        <td>コーポレート</td>
        <td>0005</td>
        <td>社員E</td>
        <td>0001</td>
        <td>A</td>
    </tr>
</table>
ここでいう候補キーは<b>会社ID、社員ID、チームID</b>です。
<br>
部分関数従属を探します。
<br>
<b>会社ID</b>が決まると、<b>会社名、所属ID、所属名</b>が決まります。
<br>
<b>社員ID</b>が決まると、<b>社員名</b>が決まります。
<br>
<b>チームID</b>が決まると、<b>チーム名</b>が決まります。
なので以下の形にマスタを分けます。


<h4>■第二正規化</h4>
<h5>会社マスタ</h5>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
        <td>所属ID</td>
        <td>所属名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
        <td>0002</td>
        <td>コーポレート</td>
    </tr>
</table>

<h5>社員マスタ</h5>
<table>
    <tr>
        <td>社員ID</td>
        <td>社員名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>社員A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>社員B</td>
    </tr>
    <tr>
        <td>0003</td>
        <td>社員C</td>
    </tr>
    <tr>
        <td>0004</td>
        <td>社員D</td>
    </tr>
    <tr>
        <td>0005</td>
        <td>社員E</td>
    </tr>
</table>

<h5>チームマスタ</h5>
<table>
    <tr>
        <td>チームID</td>
        <td>チーム名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>B</td>
    </tr>
    <tr>
        <td>0003</td>
        <td>C</td>
    </tr>
</table>
これが第二正規化です。🍺🍺





<h2>第三正規系🌀</h2>
「候補キー以外の列に関数従属している列が存在しない状態」
<br>
第二正規化のマスタを見ると、
<br>
候補キー「会社ID」に「会社名、所属ID、所属名」が関数従属しています。
<br>
それと同時に、候補キーではない「所属ID」に対して、「所属名」が関数従属しています。
<br>
そこで候補キーではない「所属ＩＤ」に従属している「所属名」を別表に写すのが第三正規化です。
<br>
<h4>■正規化前</h4>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
        <td>部署ID</td>
        <td>部署名</td>
        <td>社員ID</td>
        <td>社員名</td>
        <td>チームID</td>
        <td>チーム名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0002</td>
        <td>B</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0001</td>
        <td>社員A</td>
        <td>0003</td>
        <td>C</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0002</td>
        <td>社員B</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
        <td>0001</td>
        <td>テクノロジー</td>
        <td>0003</td>
        <td>社員C</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
        <td>0002</td>
        <td>コーポレート</td>
        <td>0004</td>
        <td>社員D</td>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
        <td>0002</td>
        <td>コーポレート</td>
        <td>0005</td>
        <td>社員E</td>
        <td>0001</td>
        <td>A</td>
    </tr>
</table>

<h4>■第三正規化</h4>
<h5>会社マスタ</h5>
<table>
    <tr>
        <td>会社ID</td>
        <td>会社名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>シアトル</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>BP</td>
    </tr>
</table>

<h5>部署マスタ</h5>
<table>
    <tr>
        <td>部署ID</td>
        <td>部署名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>テクノロジー</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>コーポレート</td>
    </tr>
</table>

<h5>社員マスタ</h5>
<table>
    <tr>
        <td>社員ID</td>
        <td>社員名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>社員A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>社員B</td>
    </tr>
    <tr>
        <td>0003</td>
        <td>社員C</td>
    </tr>
    <tr>
        <td>0004</td>
        <td>社員D</td>
    </tr>
    <tr>
        <td>0005</td>
        <td>社員E</td>
    </tr>
</table>

<h5>チームマスタ</h5>
<table>
    <tr>
        <td>チームID</td>
        <td>チーム名</td>
    </tr>
    <tr>
        <td>0001</td>
        <td>A</td>
    </tr>
    <tr>
        <td>0002</td>
        <td>B</td>
    </tr>
    <tr>
        <td>0003</td>
        <td>C</td>
    </tr>
</table>

これが第三正規化です。🍺🍺🍺

<h2>まとめ</h2>
他にも第四正規化、第五正規などがあるらしいですが、一旦は第三正規化まで説明してみました。
間違い、不足などありましたらドシドシ連絡ください！！🙇