ER図についてゼロから学ぶ。

エンジニア経験ゼロのweb系デザイナー(いにしえのhtmlコーディングしかできない)が、
半年足らずでバックエンドエンジニアとしてデビューまでの記録となるべく(する予定で必死に勉強してるのが今)
Qiita書いてます。今はMySQL動かそうとやっきになってます。
自販機作ってみたシリーズの途中ですが、ER図を書くのに調べたり学んだことがたくさんあったので、
一旦自販機は置いといて、ER図に関してまとめます。
細かい話は抜きにして、とにかく概念掴む！慣れる！を目的にまとめていきます。

# MySQL workbenchは便利らしい
目に見える形で設計を行い、ER図というものが描けるらしい。
しかも描いたER図をコードにして書き出せるらしい。
unixとlinuxの違いもわからない自分のような奴にはとても嬉しいツールっぽいじゃないか。
コード書かないで図で見えるのは優しく感じる(最終的にコード書かないと動かないので二度手間とか言わない。私のような初心者には概念を掴みやすいかどうかが重要なのです)。

## ER図ってどんなことするのさ
箱をかいて箱の中に物を入れて、それを線でつなぐと連動するらしい。
昔電気工作とかやったようなそんな気分だ。あとなんだっけな、ゲームでなんかやった気がする。まあいいです

![01.png](https://‥-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/dbe137b7-8ca4-97d0-4b8b-a61012e1a875.png)

ここに箱=「テーブル」をつくって、線で繋ぐ=「リレーション」させればいいらしい。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/d8e6dec7-1681-3fc7-d80b-734b28140548.png)
Place a new table をクリック。これでテーブルを作成する。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/5b1b5029-4d85-9db8-cf7e-bce78a3c15f0.png)
出た。
これをダブルクリックするとテーブルの中に色々書き込んでいける。
…色々ってなんだ？

### そもそもテーブルって何を書くものなんだという疑問
テーブルの中に書き込むことは

- 「誰が」
- 「なにを」
- 「どうする」

である。これがエンティティ(実体)と呼ばれるものらしい。

実際に仕事でER図を書く際には、現実に行われる業務フローやルールを表現することになる。
その実際の業務ルールの中で登場する「誰が何をどうする」をER図に落とし込み、
どんな関係性で動くのかをworkbenchのER図で正確に過不足なく表せたら、
書き出したコードも過不足なくちゃんと動いてくれるものになる、っぽい。

実際の業務ルールで現れてくるものの例：社員、在庫、売上、などなど
というわけでER図はがんばって正確なものに仕上げなくては！
業務フローをよく噛み砕いて、分析していかなくてはいけないのである！

### workbenchに戻る
さっきのテーブルをダブルクリックすると、色々な項目が出てくる。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/cd5c6df5-4fe9-e3f2-b845-a81ceed621e0.png)
ここに思いつく限りのエンティティを入れて入れて入れ込むのだ

けど、どこに何を書けばいいのかわからない。

まずはこのテーブル自体がなんなのか、メモしておかないと自分でも他人が見てもわからなくなる。
右上の下向き矢印二つ重なったようなアイコンをクリック。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/27c43076-d78d-acb8-affc-56e064641d55.png)

##### Nameのところにテーブルの名前をアルファベットで書く。
このテーブルのことを

- 正確に示す
- 簡潔な言葉
- かつ、他のテーブルと区別できて、被らない言葉

を使いましょう。

##### Commentsのところに、詳細な説明を書く。
このテーブルが何を示しているのかの説明文を書きましょう。
ここに書くのは日本語でおk。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/ca5265ca-2a16-1d5e-f907-ea9172e54fb9.png)

これでテーブル自体の名前がついた。
じゃあ改めて中に入れるもの、エンティティを作っていこう。

### なんか色々書いてある
わけわかんない。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/d2aee7d4-5a17-4983-2eb1-bb5b123db51d.png)
Datatypeはフィールドに入れるデータの型を決めるっぽいですね。
調べてみた

- 整数型(TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT)
- 浮動小数点数型(FLOAT, DOUBLE)
- 固定小数点数型(DECIMAL, NUMERIC)
- BIT型
- 日付型と時刻型(DATE, TIME, DATETIME, TIMESTAMP, YEAR)
- CHAR型とVARCHAR型
- BINARY型とVARBINARY型
- BLOB型とTEXT型
- ENUM型
- SET型

よし。わからん。もうちょい調べてみよう
#### 整数型(TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT)
INT=INTEGER。整数型というその名の通り整数を入れる。
以下、違うのは「扱える数の範囲」

###### TINYINT
符号なければ 0〜255
符号があれば -128~127

###### SMALLINT
符号なければ0〜65535
符号あれば-32768〜32767

###### MIDIUMINT
符号なければ 0〜16777215 いっせんろっぴゃくななじゅうななまんななせんにひゃくじゅうご
符号があれば -8388608〜8388607 

###### INT
符号なければ 0〜4294967295 よんじゅうにおくきゅうせんよんひゃくきゅうじゅうろくまんななせんにひゃくきゅうじゅうご
符号があれば -2147483648〜2147483647 

###### BIGINT
0〜18446744073709551615 いっせんはっぴゃくよんじゅうよんけいろくせんななひゃくよんじゅうよんちょうななひゃくさんじゅうななおくきゅうひゃくごじゅうごまんいっせんろっぴゃくじゅうご
-9223372036854775808〜9223372036854775807

#### 浮動小数点数型(FLOAT, DOUBLE)
小数点以下を扱える。
○○×△△の□□乗という形式で少数を表す。
数字を扱うときは、計算によって実際の数字を思い出させる
以下、違うのは「扱える数の範囲」

##### FLOAT
-3.402823466E+38 〜 -1.175494351E-38
0
1.175494351E-38 から 3.402823466E+38

##### DOUBLE
-1.7976931348623157E+308 から -2.2250738585072014E-308
0
2.2250738585072014E-308 から 1.7976931348623157E+308


#### 固定小数点数型(DECIMAL, NUMERIC)
小数点以下を扱える。
小数点が特定の位置にある前提。
数字を扱うときは、特定の位置に小数点を打つ。
最大桁数 (M) は 65 。デフォルトは 10。
小数部の最大桁数 (D) は 30 。デフォルトは 0。

…ちょっとよくわかんないけどどうやら基本的には浮動小数点使ったほうがいいらしい…(よくわかってない

###### なおここまで
符号無しはUNSIGNEDと呼ぶ(後に出てくる)
マイナスの数を入れたく無い場合はUNSIGNEDにする。
ZEROFILLを設定すると開いた桁数の部分に0が入る。

#### BIT型
ビット値(0と1で表される値)を格納するために使われる

#### 日付型と時刻型(DATE, TIME, DATETIME, TIMESTAMP, YEAR)
文字通り。日付、時刻などを表す
#####DATE
日付
'1000-01-01' から '9999-12-31'
フォーマット ： 'YYYY-MM-DD'

#####DATETIME[(fsp)]
日付と時間の組み合わせ
'1000-01-01 00:00:00.000000' から '9999-12-31 23:59:59.999999'
フォーマット ： 'YYYY-MM-DD HH:MM:SS[.fraction]'

#####TIMESTAMP[(fsp)]
タイムスタンプ
TIMESTAMP 値は、エポック ('1970-01-01 00:00:00' UTC) からの秒数
'1970-01-01 00:00:01.000000' UTC から '2038-01-19 03:14:07.999999' UTC
フォーマット ： 

#####TIME[(fsp)]
時間
'-838:59:59.000000' から '838:59:59.000000'
フォーマット ： 'HH:MM:SS[.fraction]' 

#####YEAR[(2|4)]
2 桁または 4 桁の形式の年
4 桁の形式では、値は 1901 から 2155 と 0000
2 桁の形式では、値は 70 から 69 ( 1970 から 2069 に相当)
フォーマット ： YYYY または YY 

#### CHAR型とVARCHAR型
CHARACTER。文字列を入れられる。
#####CHAR
固定長文字列。指定された長さになるように、右側にスペースが入る。
#####VARCHAR
可変長文字列。スペースは入らない。

#### BINARY型とVARBINARY型
データをバイナリデータとして格納する。テキストデータ以外のデータ。
(文字、画像、動画、音楽、プログラムなど)
#####BINARY型
固定長バイナリバイト。指定された長さになるように、右側に0x00が入る。
#####VARBINARY型
可変長バイナリバイト文字列。0x00 は入らない。

#### BLOB型とTEXT型

#####BLOB
巨大なバイナリデータを格納するとき使用
VARBINARY 型で格納できるバイト数を指定しなかったものと同様

#####TEXT
巨大なテキストデータを格納するとき使用

#### ENUM型
リストから選択された値を 1 つだけを持つことができます。
ENUM 値は、内部では整数として表されます。
ENUM カラムには、最大 65,535 個の個別の要素を含めることができます。
よくわからん

#### SET型
ゼロ個以上の値を持つことができます。
それぞれの値は、'value1'、'value2'、... 値のリストから選択します。
SET 値は整数として内部で表されます。
SET カラムには最大 64 個の個別のメンバーを含めることができます。
よくわからん

数値を扱うときにはVARCHAR,INT,FLOAT,DECIMALDOUBLEなどあるが、
小数点以下桁数を揃えて正確に扱うならば、decimal型またはdouble型を使う （例:緯度経度情報）
小数部を含んで6桁まで入力された通りに保存する用途であれば、float型を使う
そのまま保存したい場合には、varchar型を使う


その次にもチェックボックスが色々ある。。。なんだこれ
PK…サッカー
UQ…wifi
UN…国連
AI…イラレ

バカ言ってないで真面目に一個一個調べてみましょう。
PK 主キー Primary Key
NN NOT NULL制約 Not Null
UQ UNIQUE制約 UniQue
BIN バイナリー Binary
UN 符号なし UNsigned
ZF ゼロフィル ZeroFill
AI オートインクリメント Auto Increment
G Generated columns

##### PK 主キー Primary Key
プライマリキーに指定する

##### NN NOT NULL制約 Not Null
「Nullを入れることを許可しない」ことになる。

##### UQ UNIQUE制約 UniQue
値が重複しない

##### BIN バイナリー Binary
エンコード文字列を入れられる。

##### UN 符号なし UNsigned
0以上の値が入るようにする

##### ZF ゼロフィル ZeroFill
このフィールドが整数型なら、使われていない桁は0で埋める。
例　INT型なら最大10桁の0が、BIGINT型なら最大19桁の0が並ぶ

##### AI オートインクリメント Auto Incremental
このフィールドが整数型なら、レコードが挿入されるたびに値が+1、自動で加算される！
AIをつけると値が重複することがなくなる = PK、UQとの併用がしばしば。

##### G Generated columns
わかんない…

テーブルと同じようにColumn Nameにアルファベットで名前をつける。
Commentsに日本語で説明をつける。

##### かならずNameとCommentsは書き込むこと！！
あとで見直した時に絶対にわけわからなくなるから。必ず内容を書き込んでおくべし。

## ER図についてまとめは以上。実践編に戻る。
以上、次回は自販機でER図を作ってみます。リレーションもそこで実際につけて組んでみる。

(…自分で書いてて思うが卵が先かひよこが先か、その辺がまだ自分の中でごっちゃになっているのだなあということを感じる。とにかく知識流し込んで行く段階なのでもうこれはしょうがないと諦める。個人的な備忘録だぞこれは。頑張れ俺。)