設計初歩のER図でつまづいたので、データベースの基礎学習をする事にした

# はじめに

当記事が初投稿になるので、拙い文章になっておりましたら、恐れ入ります。
個人の学習記録として、こちらに残させて頂きます。

今回は、設計に関わる
・テーブル
・正規形
・ER図
の３つについて、まとめています。


# 投稿者の技術レベル
* エンジニア未経験の初学者
* コンピュータサイエンス、OS(Linux)、フロントエンド(HTML,CSS,JavaScript),バックエンド(Ruby,Rails),データベース(MySQL),バージョン管理(Git/GitHub)の基礎学習を学習
* 現況：WEBサービス実装前の設計段階（転職用ポートフォリオの作成途中）

# 学習した教材
おうちで学べるデータベースのきほん 木村明治



# テーブル
書籍では、テーブルを

>一意な識別子と持った共通項によってまとめられたモノの集合

と表現されている。

ここでいう**「一意な識別子」**とは
主キーのことを指している。

例えば、ユーザー情報で考えた場合、
登録されているデータが全てが一致しているユーザーが複数いる場合
特定ができないため、識別子（主キー）が必要になる。

例）
ユーザー名：名無しのnameさん、年齢：３０歳　といった登録が２名いたと仮定
↓
ID（主キー）：０１、ユーザー名：名無しのnameさん、年齢：３０歳
ID（主キー）：０２、ユーザー名：名無しのnameさん、年齢：３０歳
※主キーによって特定可能

主キーには、以下ルールが設けられているので
　1.重複は禁止
　2.NULL（空）不可
一意性を持たせる事ができる。


もう一方の**「共通項によってまとめられたモノの集合」**については
共通項　＝　カラム（列）でまとめるという事。

同じくユーザー情報で考えると
ユーザー名、年齢、性別、メールアドレスを
共通項（列：カラム）とし、整理して表せる。

例）
・ユーザー名：Aさん　年齢：２０　性別：男性　メールアドレス：a_a11a@xmail.com
・ユーザー名：Bさん　年齢：３０　性別：女性　メールアドレス：bbb33@xmail.com
・ユーザー名：Cさん　年齢：４５　性別：男性　メールアドレス：cc323@xmail.com

NGケース
・ユーザー名：Aさん　年齢：２０　性別：男性　メールアドレス：a_a11a@xmail.com
・年齢：３０　ユーザー名：Bさん 性別：女性　メールアドレス：bbb33@xmail.com
・ユーザー名：Cさん　年齢：４５　メールアドレス：cc323@xmail.com　性別：男性

カラムの列で入力データが統制されていれば
SQL文のWHERE句によって、必要なデータも取り出せる為
ルールを守る必要がある。


# 正規形

文字通り、正しく定義された形のテーブルをいう。

正規形の目的は「更新した際に異常を発生させない事」である。

正規形にはレベルがあり、第１正規形〜第５正規形まであるが
特に気を付けるべき第３正規形まで。

<br>

**第１正規形**

定義：１つのセルに複数の値を入れてはいけない

例えば、ユーザー情報に個人の趣味を入れるセルがあったとして
（読書、テニス）のように２つの値を
入れれないということ。

もしも、複数データが発生してしまうのであれば
その部分は切り取って
別テーブルに分けて表記する必要がある。

例）
■NGパターン
1.usersテーブル
・ID：１
・ユーザー名：Aさん
・趣味：読書、テニス

↓

■OKパターン
1.usersテーブル
・user_ID：１
・ユーザー名：Aさん

2.hobbiesテーブル
・user_ID：１
・hobby_id：１
・hobby:読書

・user_ID：１
・hobby_id：２
・hobby:テニス

<br>

**第２正規形**

定義：部分関数従属を発生させない

これは、複数の主キーのうち、一部によって
データが特定されるということ。

例えば、２つの主キー(user_IDとpost_ID)が設定されているケースで
３つの非主キー(ユーザー名・email・年齢)を特定できるが
そもそも特定にはpost_IDは必要かといった具合です。

■user_ID（主キー）＋　post_ID(主キー)　→ ユーザー名　email　年齢　（投稿記事）

ではなく

1.　user_ID（主キー）　→ ユーザー名　email　年齢　
2.　post_ID(主キー)　→ 投稿記事

に分けて作成すれば、それぞれ主キーによって
データの特定が可能になる。


<br>

**第３正規形**

定義：推移関数従属を発生させない

これは主キー以外の列を介して、データが特定されることを指す。

例）
user_ID（主キー）→ ユーザー名　→　投稿記事

直接的に主キーでは特定できず
ユーザー名によって、投稿記事が特定できる

これも同様に、特定できなかった列を
別テーブルに分けて作成する事で、解決する。

# ER図

ER図の目的は「テーブル同士の関係性を示す」である。

---> Entity：テーブル　Relation：関係性

正規形で、更新異常が起きにくくなった一方で
テーブルが多くなり、どのテーブルに何が
結合しているのか把握しにくくなった。

これを視覚的に把握できる様にしたものがER図と言える。

ER図の表記法はいくつかあるが、IE表記法がポピュラーで
見た目が分かりやすいので、初学者に向いている。

■参考図
![ER図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1380401/789ee5a6-99a3-77f3-66f6-431c792ac43a.jpeg)

エンティティ（テーブル）の書き方は
最上部に「テーブル名」を表記し
下段に「主キー」、更に下段に「非キー列」を書く。

テーブルとテーブルの間には、リレーションシップを
表す記号が使用する。

このER図では、Usersテーブル(ユーザー)とPostテーブル(投稿記事)を
１対多（０以上）の関係で示している。

また、Postsテーブルでは
user_idを外部キーとして設定しており
外部キー制約ができている。

これは、Usersテーブルにおいて
user_idは主キー（＝NULLではない）である為、
「Usersテーブルに存在しないユーザーは
Postsテーブルに存在できない事」を指す。

# 終わりに

Qiitaにまとめるの難しすぎる！
分かりやすく記事を書けるエンジニア凄すぎると痛感した日でした。
徐々に簡潔にアウトプットできる様に努力します。


# 参考記事

* [おうちで学べるデータベースのきほん Kindle版](https://www.amazon.co.jp/%E3%81%8A%E3%81%86%E3%81%A1%E3%81%A7%E5%AD%A6%E3%81%B9%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E3%83%9F%E3%83%83%E3%82%AF-ebook/dp/B00TTRZFDC)
* [Qiita マークダウン記法 一覧表・チートシート](https://qiita.com/kamorits/items/6f342da395ad57468ae3)
* [日本語Markdownユーザー会](https://www.markdown.jp/what-is-markdown/)