1
2

データベースの正規化

Posted at

データベースの正規化とは

データベースの設計工程において、同一テーブル内のデータの重複をなくし、データの整合性を保つためのルールや手法のことを言います。

正規化が行われていない例としては下記のようなものになります。

1. 「第一正規化」が守られていない例
→科目列の複数の値をカンマで区切って保存しており、データの更新などが複雑になる

| 学生ID | 学生名 | 科目              |
--------------------------------------
| 1      | 山田   | 数学, 英語        |
| 2      | 佐藤   | 理科, 社会        |

2. 「第二正規化」が守られていない例
→下記でいうと学生名が学生IDに依存していますが、「科目担当教師」は「科目」に依存してしています。この場合、「学生ID」だけでなく「科目」にも依存しているため、教師情報が冗長に保存されてしまいます。

| 学生ID | 学生名 | 科目       | 科目担当教師 |
---------------------------------------------
| 1      | 山田   | 数学       | 田中         |
| 1      | 山田   | 英語       | 佐藤         |
| 2      | 佐藤   | 理科       | 中村         |
| 2      | 佐藤   | 社会       | 中村         |

3. 「第三正規化」が守られていない例
→「住所」と「郵便番号」が一緒に保存されており、住所が変更されると郵便番号も変更する必要があります。
住所情報が複数のテーブルで使用される場合、住所が変更されるとすべてのレコードで更新が必要になります。

| 学生ID | 学生名 | 住所            | 郵便番号 |
------------------------------------------------
| 1      | 山田   | 東京都千代田区  | 100-0001 |
| 2      | 佐藤   | 東京都新宿区    | 160-0001 |
| 3      | 鈴木   | 神奈川県横浜市  | 220-0001 |
| 4      | 佐藤   | 東京都千代田区  | 100-0001 |

それぞれの正規化のルール

第一正規化
テーブルの各列において、各セルが単一の値を持つこと

【正しい例】
| 学生ID | 学生名 | 科目   |
-----------------------
| 1      | 山田   | 数学   |
| 1      | 山田   | 英語   |
| 2      | 佐藤   | 理科   |
| 2      | 佐藤   | 社会   |

第二正規化
第一正規化はできている上で、部分関数従属をなくすこと

ここで、部分関数従属について説明していきます。

まず、関数従属性ついて説明します。
関数従属性とは、ある列の値が他の列の値に依存して決まる関係のことです。
例えば、学生IDに対して学生名が一意に決まる場合学生名は学生IDに関係従属していると言います。

部分関数従属とは、複合キー(2つ以上の列が主キーを構成する)において、ある列が主キー全体にではなく、その一部にのみ依存している状態をいいます。

上記の2の例でいくと、科目担当教師が科目にのみ依存していることです。

【正しい例】学生と科目のテーブル
| 学生ID | 科目ID |
-------------------
| 1      | 1      |   数学科目ID 1
| 1      | 2      |   英語科目ID 2
| 2      | 3      |   理科科目ID 3
| 2      | 4      |   社会科目ID 4
【正しい例】科目と教師のテーブル
| ID | 科目   | 科目担当教師 |
-------------------------
| 1  | 数学   | 田中         |
| 2  | 英語   | 佐藤         |
| 3  | 理科   | 中村         |
| 4  | 社会   | 中村         |

第三正規化
第二正規化に従った上で、推移的関数従属をなくすこと
推移的関数従属とは、ある列が別の列に間接的に依存している状態です。
簡単に言うと、次のような関係があるとき、推移的関数従属が成立しているといいます。

列Aが列Bに依存している(A → B)
列Bが列Cに依存している(B → C)
結果として、列Aが列Cに依存している(A → C)
このとき、列Cは列Aに対して推移的に従属していると言います
【正しい例】学生テーブル
| 学生ID | 学生名 |
-------------------
| 1      | 山田   |
| 2      | 佐藤   |
| 3      | 鈴木   |
| 4      | 佐藤   |
【正しい例】住所テーブル
| 住所ID | 住所            | 郵便番号 |
------------------------------------
| 1      | 東京都千代田区  | 100-0001 |
| 2      | 東京都新宿区    | 160-0001 |
| 3      | 神奈川県横浜市  | 220-0001 |
学生と住所のリレーションテーブル
| 学生ID | 住所ID |
--------------------
| 1      | 1      |
| 2      | 2      |
| 3      | 3      |
| 4      | 1     |

まとめ

今までテーブル設計をする際に、正規化について意識していなかったので整合性が保たれていないテーブルを作っていたかもしれません。今回でしっかり理解できたので、次からは正規化を意識しながら設計を行っていければと思います!

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2