MySQL勉強まとめ

# 概要
「コードを書くエンジニアとして転職するならSQLできないとダメだよ」知人である現役エンジニアに言われた言葉です。なんなら「話にならない」とも言われ衝撃でした・・・

そこで！DMMWEBCAMPで学習期間を終えて、今更ですが、転職活動と並行してMySQLを勉強することにしました！
この記事は、勉強の中で躓いた点や気づきなどを書くことを目的にしています。

浅学非才な身ゆえ間違いなどもあるかもしれませんので、その際はご指摘いただけると幸いです。

# 環境
MySQL 8.0.32
mac



# 前提条件
Homebrewを既にインストールしているという前提で話を進めます。ご了承ください。

# 目次
- そもそもデータベースとは？
- MySQLのインストール
- データの取得の仕方
- 個人的メモ
- 参考にさせていただいたサイト

# そもそもデータベースとは？

[一週間で身につくMySQL](http://web.sevendays-study.com/mysql/index.html)のサイトにあった内容を引用させていただくと、

>MySQLについて説明する前に、データベースの仕組みについて説明しましょう。データベースとは、データの集合体という意味の言葉で、住所録や成績表などといったものもこれに含まれます。この概念は、コンピュータの世界でも同様で、データを保存し、整理、検索できれば、データベースということができるでしょう。
>
>ただ、コンピュータの世界でのデータベースというときは、現在、一般的には`リレーショナルデータベース（RDB）`のことを指すのが一般的です。

ふむふむ・・・

>リレーショナルデータベースとは、データを関連性（リレーション）によって管理するデータベースのことです。リレーショナルデータベースでは、すべてのデータを表形式で表現します。表は列（カラム）と行（レコード）で構成され、表の要素のことを、フィールドと言います。

|クラス|出席番号|氏名    |
|----|-------|-------|
|３組 |1      |山田一郎|
|３組 |2      |山田二郎|
|３組 |3      |山田三郎|
|３組 |4      |山田四郎|

上の表を例にして、サイトの記述を参考にさせていただくと、
- 横列を「行(レコード)」
- 縦列を「列(カラム)」
- 表の四角の１つ１つを「フィールド」
- 表全体を「テーブル」

というらしいです。

>現在、データベースは、一部の例外を除き、ほぼこのリレーショナルデータベースを指します。そこで、以下、リレーショナルデータベースをRDBと略すか、もしくは単にデータベースと呼ぶことにします。
>
>このような一連の操作を行うのは、SQL（Structured Query Language）というデータベース言語によって行います。現在主流のデータベースは、ほとんどがこのSQLによってデータベースの操作を行う仕組みになっています。

らしいです！

# MySQLのインストールの手順
1
```MySQL:ターミナル(mac).
macの名前 % brew install mysql
#↑を実行後、色々出てくる
```

2
```MySQL:ターミナル(mac).
macの名前 % mysql --version   
↑を実行後に出てくるやつ→mysql  Ver 8.0.32 for macos12.6 on arm64 (Homebrew)
```
mysql --versionを実行後、mysql  Ver 8.0.32みたいな記述が出て来ればインストール完了です！
Homebrewがインストールできていれば、MySQLのインストールはすぐです！

# MySQLを起動する方法
2
```MySQL:ターミナル(mac).
macの名前 % mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.32 Homebrew

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```
mysql> が出てくれば、起動完了！

# データの取得の仕方
```MySQL:ターミナル.
FROM テーブル名;
```
でテーブルを指定
```MySQLターミナル.
SELECT AVG (カラム名)
↑カラムの数値の合計値を取得
FROM テーブル名;
```

```MySQL:ターミナル.
SELECT AVG (カラム名1)
↑WHEREで検索したカラムの数値の合計値を取得
FROM テーブル名
WHERE カラム名2 = レコード名;
```

```MySQL:ターミナル.
COUNT(カラム名)
↑カラムの数を数える
※NULLのデータはカウントされない
FROM テーブル名;
```

```MySQL:ターミナル.
COUNT(*)
↑これでレコードの数を数える
FROM テーブル名;
```

```MySQL:ターミナル.
COUNT(*)
↑WHEREで検索したレコードの数を数える
FROM テーブル名
WHERE character_name = "にんじゃわんこ";
```

```MySQL:ターミナル.
SELECT MAX(カラム名)
↑カラムの最大値を取得
SELECT MIN(カラム名)
↑カラムの最小値を取得
FROM テーブル名;
```

```MySQL:ターミナル.
SELECT MAX(カラム名)
↑カラムの最大値を取得
SELECT MIN(カラム名)
↑カラムの最小値を取得
FROM テーブル名
WHERE レコード名 = "カラム名";
```

```MySQL:ターミナル.
SELECT SUM(カラム名1),カラム名2
FROM テーブル名;
GROUP BY カラム名2
↑これは、カラム名２の中で同じデータがあれば、グループに分けることができる
上の例で言うと、カラム名２を同じグループで各々まとめ、その中でカラム名１の合計値を取得する
GROUP BYのSELECTで使えるのは、GROUP BYで指定しているカラム名と、集計関数だけです
```

```MySQL:ターミナル.
SELECT SUM(カラム名1),カラム名2,カラム名3...
FROM テーブル名;
GROUP BY カラム名2,カラム名3...
↑複数のカラムをグループ化することができる
```

```MySQL:ターミナル.
SELECT SUM(カラム名1),カラム名2
FROM テーブル名;
WHERE 条件→(レコード名 = カラム名３)
GROUP BY カラム名2
↑条件で検索したレコードを選別し、カラム名２をグループ化して、カラム名１の合計値を取得する
```

```MySQL:ターミナル.
SELECT(カラム名１),カラム名２
FROM テーブル名
GROUP BY カラム名２
HAVING 条件(カラム名1 > 1000);
↑グループ化してテーブルから合計値を出すが、その際にpriceが1000以上のものを取得する
HAVINGはグループ化させたものの中から選別して取得する
```

#### サブクエリ
通常のクエリだけであれば二度手間、三度手間になることがあります。
例えば、「ムバッペより得点をとった選手を調べたい」というときに↓
```MySQL:ターミナル.
SELECT goals
FROM players
WHERE name = 'ムバッペ';
```
```MySQL:ターミナルの結果.
5
```
↑をしてから
```MySQL:ターミナル.
SELECT name
FROM players
WHERE goals > 5;
```
```MySQL:ターミナルの結果.
メッシ
リシャルリソン
豪炎寺
```
という二度手間になリます。
なので、サブクエリというものを設定して、一度の処理にまとめてしまいます。
↓処理は先ほどの「ムバッペより得点をとった選手を調べたい」時の処理で行います。

```MySQL:ターミナル.
SELECT name  ...③
FROM players
WHERE goals >(   ...①
    SELECT goals
    FROM prayers
    WHERE name = 'ムバッペ'   ...②
);
```
① サブクエリの範囲を探す
② プレイヤーテーブルから(FROM players)ムバッペという名前の選手を探し(WHERE name = 'ムバッ ペ')、ムバッペのゴール数を検索する(SELECT goals)
③ ②で探した範囲より多い選手を検索する(SELECT name)
この順に処理していきます。
```MySQL:ターミナルの結果.
メッシ
リシャルリソン
豪炎寺
```
このように処理を１つにまとめることができます。

#### AS
実行した結果の名前がわからなくなることを防ぎます。

```MySQL:ターミナル.
SELECT name
FROM players
WHERE height >= 180;
```
|height|
|------|
|ジョン|
|ランス|
|パンク|
|オメガ|

など、カラムの名前が表のタイトルになるので、「身長が180cm以上の選手」であることが表のタイトルを見ても、ピンと来ません。
そのため、ASでカラムの名前を指定することができます。
SELECT name AS '身長180cm以上の選手'
FROM players
WHERE height >= 180;
|身長が180cm以上の選手|
|------|
|ジョン|
|ランス|
|パンク|
|オメガ|

#### 主キーと外部キー
playersテーブル
|id|name|country|rank|
|--|----|----------|-|
|1|大迫|日本|3|
|2|アンドレス|スペイン|2|
|3|ムバッペ|フランス|1|
|４|田中|日本|3|

このように、主キーと外部キーを使わず、1つのテーブルで行うと、日本のランクが変わった時に、「大迫」と「田中」の２つのランクを変えないといけません。これは手間です。

playersテーブル
|id|name|country_id|
|--|----|----------|
|1|大迫|1|
|2|アンドレス|3|
|3|ムバッペ|2|
|４|田中|1|

countriesテーブル
|id|name|rank|
|--|----|----|
|1|日本|3|
|2|フランス|1|
|3|スペイン|2|

こうすることによって、日本のランクが変わったとしても、countriesテーブルにある日本のランクを１つ変えれば大丈夫です。データの量が増えれば増えるほど役に立ちます。



```MySQL:ターミナル.
SELECT
FROM
WHERE;
```

```MySQL:ターミナル.
SELECT
FROM
WHERE;
```

```MySQL:ターミナル.
SELECT
FROM
WHERE;
```

#### 大事なこと
処理の実行の順番は
1. WHERE
1. GROUP BY
1. 集計関数


# 個人的メモ
テーブルはインデックスのまとまり→データベース

インデックス→テーブルの検索速度の向上のためのもの

データベースを動作させるための命令→クエリ

クエリのまとまり→トランザクション（トランザクションはクエリが全て成功しなければ結果は反映されない）
トランザクションに関してコミット(COMMIT)とロールバック(ROLLBACK)ができる
→処理の確定はコミット、変更処理を取り消す場合はロールバック。ただし、コミットしたものをロールバックはできない

CHARとVARCHAR→共に文字列型、CHAR(5)と入力すると、文字列を５文字まで入力可能。ただし、DOGみたいに3文字入れると、２文字分余りのスペースが空く。VARCHAR(5)と入力すると、文字列を５文字まで入力可能だが、DOGみたいに３文字入れるとカラムの長さは3文字で表される。VARCHARでは空きスペースが発生しない

日付、時刻型の入力→「"」か「'」で囲う

SQL文の命令→DDLとDMLとDCLがある
DDL→データベースやテーブルを作成するときに使う
⇨CREATE(作成),ALTER（変更）,DROP（(__データベース__,__テーブル__)削除）
DML→データを操作するときに使う（テーブルからデータを取得、テーブルにデータを追加）
⇨INSERT(レコードの追加),DELETE（レコードの削除）,UPDATE（レコードの更新）,SELET（レコードの取得）
DCL→コミットやロールバックを使う
⇨COMMIT(更新処理の確定),ROLLBACK（更新処理の放棄）,SAVEPOINT（セーブポイントの放棄）


# 参考にさせていただいたサイト
[一週間で身につくMySQL](http://web.sevendays-study.com/mysql/index.html)
[MySQL のインストール方法 - Mac](https://mysql.sql55.com/env/how-to-install-mysql-mac.php)
[progate](https://prog-8.com/dashboard)