データベース(MySQL)

# データベース(DB)とは
- たくさんのデータを一元管理し、データの保存、取得することに特化したソフトウェア(ミドルウェア)
※データベースは**データを永続的に保存する**のに適している

# リレーショナルデータベースの構成
- **1つのアプリケーションに対して1つのデータベース**があり、**1つのデータベースの中に複数のテーブル**(表)があります。
- 1つ1つのテーブル(表)は、その名の通り**Excelシートと同じように縦横の表**となっているというイメージを持ってください。Excelで例えると、Excelファイルが1つのデータベースであり、その中にある複数のシートがテーブルにあたり、シートの中の1つ1つのセルが具体的なデータとなります。
<img width="100" alt="スクリーンショット 2022-08-26 17 33 48" src="https://techacademy.s3.amazonaws.com/bootcamp/first-programming/mysql/7-1.png">

`リレーショナルデータベースの特徴`
- テーブルは、カラム(縦)とレコード(横)で構成される
- カラムに、保存するデータの制約を設定できる
- データの保存や取得には、SQLという言語を使用する

`テーブルは、カラム(縦)とレコード(横)で構成される`
- テーブルにおいて、縦をカラム(column)と呼び`横をレコード(record)と呼びます。
<img width="300" alt="スクリーンショット 2022-08-26 17 33 48" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1495496/a805498d-7e50-df37-d8f2-2b95915c666b.jpeg">

`カラムに、保存するデータの制約を設定できる`
- 制約を設定することで、データの整合性や一貫性を保ちます。
- 制約の一つとして**データ型**があります。
- 下記のキャプチャのように、idには**int**という整数型が、nameには**varchar**という文字列型が設定されています。
- カラムで指定された型以外の含んだレコードは保存できません。
<img width="300" alt="スクリーンショット 2022-08-26 17 33 48" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1495496/ae0e5d97-d620-f0ff-15e7-40522ddff0f0.jpeg">

※テーブル内のカラムにおけるデータ型

> ・他には、NULL許容/禁止の制約もあります。NULLとは**【なにも値がないこと示す】値**です。NULLを許容したカラムにはNULLを保存できますが、NULLを禁止したカラムにあNULLは保存できません。
・また、主キー(プライマリーキー)という制約も設定できます。主キーは1つのテーブルに対して1つだけ指定できます。

### データの保存や取得などの処理にSQLという言語を使用する
- ユーザテーブル（users）から全員分の名前（name）を取得するには、下記のような命令文となります。

```
select name from users;
```

※まとめ、このようにリレーショナルデータベースソフトウェアは1つのデータベースとそれに紐付いた複数のテーブルを持ち、各テーブルにはカラムの制約によってデータの整合性を担保したレコードが保存されています。

## CRUD
- データベースがデータが扱う基本操作には、次の4つがあります。
 
| 英語 | 日本語 |
| :-- | :-: |
| Create | 作成・保存 |
| Read | 取得 |
| Update | 更新 |
| Delete | 削除 |

## SQLとは
* SQLは、RDBMSのデータ操作や定義を行うための言語です。
  * データ操作のSQL
  * データの定義のSQL
  * データ制御のSQL

`データ操作のSQL`
- データ操作のSQLは、CRUDです。データの保存、取得、更新、削除を担います。アプリケーション上では、メインとなるSQLです。
 
| データ操作のSQLキーワード	 | CRUD | 用途 |
| :-- | :-: | :-- |
| INSERT | Create |作成・保存 |
| SELECT | Read | 取得 |
| UPDATE | Update | 更新 |
| DELETE | Delete | 削除 |

`データ定義のSQL`
- データ定義のSQLは、データ自体ではなく、データを格納するためのデータベースやテーブルを作成するときに使います。
 
| データ定義のSQLキーワード	 | 用途 |
| :-- | :-: |
| CREATE | 新しいデータベース、テーブルを作成する |
| DROP | すでに存在するデータベースや、テーブルを削除する |

`データ制御のSQL`
- アカウントにおけるデータのアクセス制御に使います。
- データベースは、**アカウントによって異なる権限を設定できます**。すべてのデータにアクセスできるアカウントもあれば、新規データの保存のみでデータ削除は禁止されているアカウントを作成することもできます。
- また、アカウントごとの操作記録(ログ)をとることも可能です。


## データベースサーバとは
- データベースサーバは起動すると、接続待ち状態になります。データベースクライアントからリクエストを送り、【IDとパスワードを送信してログイン】に成功すると、データベースと接続でき、データベースに対してSQLを実行できるようになります。

<img width="300" alt="スクリーンショット 2022-08-26 17 33 48" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1495496/0bb2e516-b7b9-80f0-9889-dcf03c91abab.png">

## データベースサーバの起動と停止
```
・起動
$ sudo service mysql start

・起動状態確認
$ sudo service mysql status

・停止
$ sudo service mysql stop
```

## データベースサーバへの接続
```
・起動状態確認
$ sudo mysql -u root

・停止
$ mysql -u root
```
<img width="300" alt="スクリーンショット 2022-08-26 17 33 48" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1495496/9d392923-7413-f1e0-9c0d-59f9dafe338f.png">

※これは**root**というユーザー(**-u**で指定)でMySQLサーバに接続するという意味です。

### データベースの作成
```
$ CREATE DATABASE bookstore;
```

### データベース一覧の確認
```
$ show databases;
```

### データベースを削除したいとき
```
$ DROP DATABASE bookstore;
```

### 操作するデータベースを選択
```
$ USE bookstore;
```

### テーブルの設計内容を確認
```
$ DESCRIBE books;
```

---

### データの作成・保存
```
INSERT INTO テーブル名 (カラム1, カラム2, ...) VALUES (値1, 値2, ...);
```
※　INSERT構文


### データの取得
```
SELECT カラム名 FROM テーブル名;
```
※　SELECT構文


### データの更新/確認
```
# データ更新
UPDATE テーブル名 SET カラム名1 = 値1, カラム名2 = 値2, ...

# 確認
mysql> SELECT * FROM books;
```
※　UPDATE構文


### データの削除
```
DELETE FROM テーブル名;
```
※　DELETE構文

## WHERE句をつけたCRUD操作
- INSERT
   - まずは、いくつかテスト用のレコードを追加しましょう。 
   - なお、INSERT文はデータを作成するものであり、条件をつける意味がないため、WHERE句はありません。
```
mysql> INSERT INTO books (title, price) VALUES ("はじめてのMySQL", 2980);
mysql> INSERT INTO books (title, price) VALUES ("はじめてのRuby", 1980);
mysql> INSERT INTO books (title, price) VALUES ("はじめてのHTML", 1000);
mysql> INSERT INTO books (title, price) VALUES ("はじめてのCSS", 1000);
```

- SELECT
   * 先ほど取得できたのはテーブルに保存された全レコードでした。
   * 条件を指定して、特定のレコードだけ取得したい場合には、WHERE句を用います。
   * 下記SQLは、priceが1500より大きいレコードのみを取得します。
```
mysql> SELECT * FROM books WHERE price > 1500;
```

- UPDATE
   * 下記SQLは、priceが1000のレコード（2つある）について、priceを1200へ更新するSQLです。
```
mysql> UPDATE books SET price = 1200 WHERE price = 1000;
```

- DELETE
   * 下記SQLは、titleがはじめてのCSSとなっているレコードが削除されます。
```
mysql> DELETE FROM books WHERE title = "はじめてのCSS";
```

## WHERE句で使える比較演算子
- =と>は先ほど使用しましたが、それ以外にも使える比較演算子がいくつかあります。


| 比較演算子 | 意味 |
| :-- | :-: |
| a = b	 | aとbが等しい |
| a != b | aとbが等しくない |
| a < b	 | aがbより小さい |
| a <= b | aがb以下 |
| a > b	 | aがbより大きい |
| a >= b | aがb以上 |
| a IS NULL | aがNULL |
| a IS NOT NULL | aがNULLでない |
| a BETWEEN b1 AND b2 | aがb1とb2の間 |
| a IN (b1, b2, …) | aがカッコ内の値（b1, b2, …)のいずれかと等しい |


## ORDER BY句で順番を決める
```
# 小さい順（降順）への並び替え
SELECT カラム名 FROM テーブル名 ORDER BY カラム名;

# 大きい順（降順）への並び替え
mysql> SELECT * FROM books ORDER BY price DESC;
```
※　ORDER BYを使ったSELECT文の書式


## COUNT関数
```
SELECT COUNT(*) FROM テーブル名;

# WHEREを使って対象を絞り込みたい場合

mysql> SELECT COUNT(*) FROM books WHERE price > 1500;
```
※ COUNT関数の書式

## SUM関数
```
SELECT SUM(カラム名) FROM テーブル名;
```
※ SUM関数の書式


## AVG関数
```
SELECT AVG(カラム名) FROM テーブル名;
```
※ AVG関数の書式

## テーブルの結合
```
mysql> SELECT * FROM books INNER JOIN chapters ON books.id = chapters.book_id;
```
※ テーブルの結合には、 **INNER JOIN テーブル名 ON 条件** キーワードを使用します。

## 集計関数とグループ化
```
mysql> SELECT *, COUNT(*) FROM chapters GROUP BY book_id;
```

## データ型
- INT（整数）
- DOUBLE（小数）
- VARCHAR（可変長の文字列）
- TEXT（文章用の長い文字列）
- TIMESTAMP（日付時刻型）

# (おまけ)
- joinによる結合とは、
  * データベースにおいて複数のテーブル関連づけることで、`1つの新しい仮想テーブルを作り出す操作です`。joinによる結合には、主に内部結合と外部結合の2つがあります。
- 内部結合とは
  * 結合する2つのテーブルの共通する列を基準に、`両方のテーブルからデータを抽出し`、新しい仮想テーブルを作り出します。
- 外部結合とは
  * 結合する2つのテーブルのうち、`片方のテーブルにしか存在しないデータを抽出する`ために使用されます。
- 外部キー制約とは
  * データベースにおいて`2つのテーブル間の関連性を定義するための機能`です。
  * `外部キーは`、あるテーブルの列にある値が、別のテーブルの列に値と一致する必要があることを示します。これにより2つのテーブルのデータを関連づけることができます。
  * `外部キー制約により`、データベース内の整合性を保つことができます。例えば、注文と顧客という2つのテーブルがある場合、注文テーブルには顧客IDが含まれていることが多いです。
  * 注文テーブルの顧客ID列に外部キー制約を設定することで、`注文の顧客IDが顧客テーブル内に存在することを保証する`ことができます。このように、外部キー制約は、データの整合性と参照の一貫性を保つために非常に重要な機能です。