データベースの正規化についてまとめてみた

# はじめに
データベースの正規化についてまとめてみました

# データベースの正規化とは
データベースの正規化とは**データの重複をなくし、データの更新に適したテーブルとなるように整理する作業**の事を言います

### 正規化していない例
#### employeesテーブル
|id  |name  |department  |
|---|---|---|
|1  |田中  |開発部  |
|2  |高山  |開発部  |
|3  |佐藤  |営業部  |
|4  |梓沢  |開発部  |

上のemployeesテーブルの開発部という部署名がアプリケーション開発部に変更になったとすると

|id  |name  |department  |
|---|---|---|
|1  |田中  |**アプリケーション開発部**  |
|2  |高山  |**アプリケーション開発部**  |
|3  |佐藤  |営業部  |
|4  |梓沢  |**アプリケーション開発部**  |

**1行ずつ変更しなければいけない**

### 正規化している例
emplyeesテーブルとdepartmentsテーブルと分ければ変更が１箇所のみで済む
#### employeesテーブル
|id  |name  |department_id  |
|---|---|---|
|1  |田中  |1  |
|2  |高山  |1  |
|3  |佐藤  |2  |
|4  |梓沢  |1  |

#### departmentsテーブル
|department_id  |department_name  |
|---|---|
|1  |開発部 → **アプリケーション開発部** |
|2  |営業部  |
|3  |経理部  |
|4  |総務部  |

このように、データ更新の際に複数行のデータを更新しなくてはいけないような構造を、1箇所の更新で済むように変える作業を**正規化**と言います

# データベースの正規化で出てくる用語
データベースの正規化では以下の4つのキーワードがよく出てくる

## 従属
データベースの正規化において、**従属する**というのは、特定の関連性や依存関係を指します。
具体的には、データベースのテーブルの中で、ある属性(列)が他の属性に従属しているということを意味します。

### 従属している例
この場合、gradesテーブルの`student_id`はstudentsテーブルの`student_id`に従属しています。
特定のgradesレコードは一意の学生に紐づいており、異なる`student_id`の成績には影響を与えません。
#### studentsテーブル
| student_id | student_name     | birth_date    | department      |
|--------|---------|-------------|---------------|
| 1      | 山田太郎 | 2000-05-10  | 工学部        |
| 2      | 田中花子 | 1999-12-25  | 文学部        |
| 3      | 佐藤健太 | 2001-08-02  | 経済学部      |
| 4      | 鈴木美咲 | 2002-03-15  | 法学部        |

#### gradesテーブル
| grade_id | student_id | subject     | score |
|--------|--------|-------------|---------|
| 1      | 1      | マクロ経済学入門       | 85      |
| 2      | 1      | English Conversation       | 78      |
| 3      | 2      | 日本文学入門       | 92      |
| 4      | 3      | マクロ経済学入門       | 79      |
| 5      | 3      | English Conversation       | 88      |
| 6      | 3      | 力学入門       | 70      |
| 7      | 4      | 基礎化学       | 91      |

## 主キー
**主キー**とはデータベースの項目に設定されるもので、**設定した項目データを一意に識別するために使われるもの**となります。
**Primary Key**とも言ったりします。

つまりは主キーを設定すれば**重複するデータ、同じデータがテーブル上には存在しなくなる**ということ

### 主キーが設定されている例
#### customersテーブル
`customer_id`が主キー
| customer_id | customer_name        | tel_number         | address             |
|---------------|------------|-----------------|--------------------------|
| 1001          | 山田太郎    | 010-0000-0000   | 東京都      |
| 1002          | 田中花子    | 020-0000-0000   | 大阪府     |
| 1003          | 佐藤健太    | 030-0000-0000   | 福岡県      |
| 1004          | 鈴木美咲    | 040-0000-0000   | 北海道      |

## 候補キー
**候補キー**とは主キーになりえる項目のことを言います。

### 候補キーが設定されている例
#### productsテーブル
`product_id`が主キー、`barcode`が候補キー
| product_id | barcode | product_name       | price      | stock     |
|---------------|------------------|------------|-----------|-----------|
| 1001          | 1234567890123    | ノートパソコン | 80000   | 10       |
| 1002          | 9876543210987    | スマートフォン | 50000   | 20       |
| 1003          | 5678901234567    | タブレット     | 30000   | 15       |
| 1004          | 4567890123456    | デスクトップPC | 60000   | 5        |

## 外部キー
**外部キー**とはある項目に対して、**別のテーブルの特定の項目にのみ含まれる値しか入れられない項目のこと**を言います。 
**Foreign Key**とも言ったりします。

### 外部キーが設定されている例
`customer_id`がordersテーブルで外部キーになっている
#### customersテーブル
`customer_id`が主キー
| customer_id | customer_name        | tel_number         | address             |
|---------------|------------|-----------------|--------------------------|
| 1001          | 山田太郎    | 010-0000-0000   | 東京都      |
| 1002          | 田中花子    | 020-0000-0000   | 大阪府     |
| 1003          | 佐藤健太    | 030-0000-0000   | 福岡県      |
| 1004          | 鈴木美咲    | 040-0000-0000   | 北海道      |

#### ordersテーブル
`ordered_id`が主キー、`customer_id`が**外部キー**
| ordered_id | customer_id | product_name        | ordered_date           |
|---------------|------------------|---------------|--------------------|
| 2001          | 1001             | ノートパソコン   | 2023-07-20         |
| 2002          | 1003             | スマートフォン   | 2023-07-21         |
| 2003          | 1002             | タブレット       | 2023-07-22         |
| 2004          | 1001             | デスクトップPC   | 2023-07-23         |





# 参考にしたもの
[データベースの正規化についてわかりやすく！考え方や解き方を図解を含めて解説【情報処理技術者-データベース】](https://pyming.info/2022/04/05/it_dbnormalize/#index_id0)