第3章 論理設計と正規化 ～なぜテーブルは分割する必要があるのか？

DB設計を考えるに当たり以下のポイントを注視しよう。

1. DBテーブルは関連ある情報のかたまり。
2. 一意のあるキーが必ず存在する
テーブルに複数同義レコードは、存在してはならない。一意のあるキーを置くことで、
同義のレコードが複数テーブルに存在することを防ぐことができる。

::: note warn
※一意のあるキーは、固定超文字列にする必要あり。可変長文字列のキーを設定すると、スペースが存在するだけで、同一文字列とみなされない危険性が伴うからである。
EX. 「山田　花子」と 「山田花子」
:::

3. 制約
    1参照整合性制約

    2.NOT NULL制約
    基本的にNULLは列にテーブル値にふさわしくない。できれば、列にNULL値を避けたいところ。→NOT NULL制約を設けることで、NULL値を列に対してNGにすることが可能である。

    3.CHECK制約
    ある列に対して、値の範囲に制約を設けることができる。テーブルに対して、複数の制約を設けることができる。ただし、複数列にまたがる制約はできない。(A列の値 > B列の値)

EX.
年齢 「20~30歳など」

    4.一位制約
    ある列に対して「一意のある制約」を持たせるためにある。主キーについては
    「テーブル」に対して、一つのみ主キーを持つのに対して、一意のある制約は制限なし。

◆正規化とは?

正規化とは、「DBで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式」。
※冗長性・・複数テーブルに同列のカラムや値が存在し、非一貫性のあるテーブルになってしまう。更新をかける際に、一部のデータが更新されないなどのことが起こってしまう。

正規化には第1〜第５正規形まである。

第一正規形とは?

第一正規形とは、「テーブル列に対して1つの値が存在する正規形である。」
*スカラー値と呼ぶ*

なぜ、スカラー値出ないといけないのか？

第二正規形とは?
第二正規形のテーブルは、「完全関数従属」が成立するテーブル。
部分関数従属を解消できるテーブル。
どういうことかといえば、

TBL
食品テーブル
食品ID   食品種類 食品名      会社ID  会社名
A1       お菓子　　　　　　ハイチュ○   a1     　a1株式会社
B1       肉　　　　　　　　　　　　牛肉       b1　　　　　　　　　　　b1株式会社


食品ID(X)→食品種類や食品名
会社ID(X')→会社名

どちらも、「上記のTBLだと」部分関数従属が成立する。

食品会社
会社ID  会社名
a1     　a1株式会社
b1　　　　　　　　　　　b1株式会社


これだと、食品IDや食品名などがわからないと,NULL値を入れないといけなくなる。
また、運用を誤ると　間違った値を入れる羽目になってしまう。

以上の点から、第二正規形にすることで、部分関数従属を解消し、完全関数従属ルールが成立する。

第三正規形とは?
推移的関数従属を防ぐためにある。
どういうこと?

| 食品分類ID | 食品分類 | 会社ID | 会社名   | 食品名               | 食品種類ID | 食品種類名   | 
| ---------- | -------- | ------ | -------- | -------------------- | ---------- | -------- | 
| E1         | 食べ物   | A1     | uha      | ハイチュ◯           | G1         | グミ     | 
| D1         | 飲み物   | B1     | スタバ   | スタバ アイスコーヒ  | C1         | コーヒー | 
|            |          | C1     | ドトール | ドトールアイスコーヒ | C1         | コーヒー | 


推移的関数従属とは、推移しながら、関数従属関係が成立することである。

{食品分類ID, 会社名ID}   → [食品分類ID]

 {食品分類ID}    →[食品種類名]

が成立する。つまり推移しながら、関数従属が成立するのである。

これだと(推移的関数従属だと)、会社名が存在しない場合など、「どこかのカラム(列)」
に対して、値が存在しない(スカラー値TBLが存在しない)場合はテーブルとして不成立。
→登録できない。

しかし、テーブルを独立させることで、「キー列に対して、非キー列が従属するようになる」
つまり、{X}→[Y]が成立する。


| 食品分類ID | 食品分類名 | 
| ---------- | ----------|
| E1         | 食べ物     | 
| D1         | 飲み物     | 


と
| 会社ID | 会社名   | 食品名                  | 
| ------ | -------- | ----------------------- | 
| A1     | uha      | ハイチュ◯              | 
| B1     | ドトール | ドトール アイスコーヒー | 
| C1     | スタバ   | スタバ アイスコーヒー   | 

と

| 食品種類ID | 食品種類名 | 
| ---------- | ---------- | 
| G1         | グミ       | 
| C1         | コーヒー   | 
| C1         | コーヒー   | 



そうすることで、値が存在しない場合も登録できないことなどは生じない。

また、第二正規形の時と同様に、無損失分解も可能である。
つまり、第3正規形にTBLを変形したとしても、結合させることで元のテーブル
キー列が複数存在するTBLに戻すことができる。


| 食品分類ID | 食品分類名 | 
| ---------- | ----------|
| E1         | 食べ物     | 
| D1         | 飲み物     | 


と
| 会社ID | 会社名   | 食品名                  | 
| ------ | -------- | ----------------------- | 
| A1     | uha      | ハイチュ◯              | 
| B1     | ドトール | ドトール アイスコーヒー | 
| C1     | スタバ   | スタバ アイスコーヒー   | 

と

| 食品種類ID | 食品種類名 | 
| ---------- | ---------- | 
| G1         | グミ       | 
| C1         | コーヒー   | 
| C1         | コーヒー   | 


⇨ (結合させる)

| 食品分類ID | 食品分類 | 会社ID | 会社名   | 食品名               | 食品種類ID | 食品種類名   | 
| ---------- | -------- | ------ | -------- | -------------------- | ---------- | -------- | 
| E1         | 食べ物   | A1     | uha      | ハイチュ◯           | G1         | グミ     | 
| D1         | 飲み物   | B1     | スタバ   | スタバ アイスコーヒ  | C1         | コーヒー | 
|            |          | C1     | ドトール | ドトールアイスコーヒ | C1         | コーヒー | 


元に戻せるということです。

長くなるので、ここで一旦、3章は終えます。よろ論理設計のお話もありますが、それは
「EXTRA」という形で後ほど公開予定です。