【Laravel勉強会Day6】データベース周りの環境構築

#はじめに
前回：[Laravelの簡単な操作](https://qiita.com/keinko/items/cdb71eaa9b508c735cd3)
前回はLaracastsの*Section2: Routing*まで進めました。
今回は*Section3: Database Access*を進めたいところなのですが、これを進めるには追加で環境構築を行う必要があるのでそれについてまとめます。
「環境構築」と聞いてめんどくさい気持ちになるかもしれませんが、環境構築自体はこれでおそらく最後なんで頑張っていきましょう…！

##概要
今回やることは大きく分けて二つ。

- 仮想OS上でのデータベース管理システムの設定
- ホストOS上へのデータベース可視化ツールのインストール、設定

ざっくりでいいので、「仮想OSにデータベースを作って、それをホストOSからいじれるようにするんだな」程度の認識で大丈夫です。

###データベースとは
ここで言う「データベース」はデータベースサーバのことです。
ざっくり説明するとユーザーのid、パスワード等の情報や商品の値段やカテゴリ等を保存する場所、およびコンピュータのことを指します。
もっと知りたい人は以下を参照してください。
https://wa3.i-3-i.info/word14407.html

このデータベースを管理するものがデータベース管理システムです。
今回は"mysql"と呼ばれるデータベース管理システムを使用します。
現在、仮想環境上でLaravelを動かしてきましたが、データベース管理システムも同じ仮想環境上にインストールして動かしていきます。
実際のWebアプリ開発の現場ではLaravelを動かすコンピュータ(サーバ)とデータベースを管理するコンピュータ(サーバ)を分けて用意します。

##仮想OS上でのデータベース管理システムの設定
実は[Day3](https://qiita.com/keinko/items/450561b37fede094a117)ですでにmysql自体はインストールしていました。
途中から読んでいる人は以下を仮想OS上で実行してください。

```terminal:
$ sudo apt install mysql-server php-mysql
```

###最初の設定
まず以下のコマンドでパスワードを設定します。
パスワード名は「password」でOKです。
それ以外は言われるがままに「y」か「0」を入力してください。

```terminal
$ sudo mysql_secure_installation
```

では実際にmysqlを実行しましょう。ユーザー名とパスワードを`$ mysql -uroot -ppassword`というように記述して実行することができます。
`-u`以降がユーザー名、`-p`以降がパスワードです。
`-u`とユーザー名の間はスペースで間を空けても空けなくてもどちらでも構いません。
`-p`も同様です。
ただ、実行しても以下のようにエラーになると思います。

```terminal
$ mysql -uroot -ppassword
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```

というのも、一番最初の実行にはsudo権限が必要らしいので以下のように実行してください。

```terminal
$ sudo mysql -uroot -ppassword
```

すると`mysql> `という文字が表示されると思います。
ここにSQLと呼ばれるプログラミング言語のようなものを入力することによってデータベースの操作が行えます。
まずはsudo権限なしにmysqlを実行できるように以下を入力しましょう。

```sql
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
mysql> FLUSH PRIVILEGES;
```

mysql自体は「control (Ctrl)」＋「D」で終了できます。
終了したら今度はsudo権限なしにmysqlを実行してみましょう。

```terminal
$ mysql -uroot -ppassword
```

エラーなく実行できたでしょうか？？
これでmysqlはインストール、および仮想環境上での設定は完了です。

##番外編: mysql修行の道
ここまでできればmysqlを操作することが可能となります。
ここで、実際にmysqlというものがどんなものなのか理解したくなった方がいれば下記リンクの記事がおすすめです。
https://qiita.com/devopsCoordinator/items/9b70e506150888e190be
とてつもなく良い内容です。最後までやりきることをおすすめします。
僕もお世話になりました。

ただ、勉強なんていいから早く先に進みたい方はやらなくても大丈夫です！
別に今やる必要はありません。後々、やりたくなる時が来るはずです。
僕もそのうちの一人でした。
なんとなく操作できるようになってから、実際にどういう構造なのか知りたくなって後から勉強するのも全然ありです！
まあ、IT系の企業に就職するならmysqlの操作はできて損することはないと思います。

###mysql修行の環境構築
一応、上記リンクで勉強をする人のために、僕らの環境におけるmysql操作についてまとめておきます。
まず、以下のコマンドが至るところに書いてありますが、Ubuntu環境ではUbuntuを起動したらmysqlも一緒に起動される仕組みとなっているので実行する必要はありません。

```terminal
$ mysql.server start # 僕らはこれをやる必要ないよ
```

また、[*第5章 SQLへの道 〜絞込編〜*](https://qiita.com/devopsCoordinator/items/dca5aa9c155292f1c6ea)から擬似データをインストールしてそれを扱って勉強していきます。
僕らの環境では以下のように実行してインストールしてください！

```terminal
$ cd
$ sudo apt install git
$ git clone https://github.com/TEMONA/mysql_study
$ mysql -uroot -ppassword
```

mysqlが立ち上がるので以下を入力。

```sql
mysql> CREATE DATABASE mysql_study;
mysql> exit;
```

最後に以下を実行することでインストール完了です。

```terminal
$ cd ~/mysql_study
$ mysql -uroot -ppassword -hlocalhost --default-character-set=utf8 mysql_study < data/mysql_study.backup
```

なんかWarningが表示された気がしますが気にせずに。

###インストール完了の確認
試しにいろいろと実行してみましょう。`$ mysql -uroot -ppassword`でmysqlを実行して以下をいろいろ入力してみてください。

```sql
mysql> SHOW DATABASES;
mysql> USE mysql_study;
mysql> SHOW TABLES;
mysql> SELECT * FROM areas;
mysql> SELECT * FROM genders;
mysql> SELECT * FROM lineitems;
mysql> SELECT * FROM orders;
mysql> SELECT * FROM prefectures;
mysql> SELECT * FROM users;
```

保存された擬似データがいっぱい表示されると思います。
<img width="1301" alt="スクリーンショット 2020-03-09 16.38.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/5b924c1b-1c8f-4c79-c906-c1766ecd951e.png">
これでmysql修行のための環境構築は終わりなのでバリバリ1章からやってみてください。

##データベース可視化ツールのインストール
修行の話が長くなってしまいましたが、あれはメインではありません。
話を戻しましょう。
次にホストOSで仮想環境上に構築したデータベースを見やすく表示したり、簡単に編集できるようになる可視化ツールをインストールしましょう。
###DBeaverのインストール
可視化ツールはなんでもいいんですが、自分が使ってるのでDBeaverについて説明していきます。
いつもの通り公式サイトから自分のホストOSにあったものをインストールしましょう。
https://dbeaver.io/download/

###VirtualBoxの設定
[前々回](https://qiita.com/keinko/items/842e7c3c939276d7646c)の「ホストマシンのブラウザでWebサイトを見れるよう設定」の章と同じようなことをして、ホストOS上で仮想OSのデータベースにアクセスできるようにします。

1. VirtualBoxで使用している仮想環境を選択し、「設定」→「ネットワーク」で「高度」をクリック
<img width="886" alt="スクリーンショット 2020-03-06 10.53.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/9366277f-599a-6a21-d7f6-eee3bd8a0a58.png">
2. 「割り当て」が"NAT"であることを確認して、「ポートフォワーディング」をクリック
<img width="886" alt="スクリーンショット 2020-03-06 10.54.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/6307d7d0-1312-6250-48fc-bcfc15e191a5.png">
3. プラスマークをクリックして、「名前」に好きな名前、「プロトコル」に「TCP」、「ホストポート」に好きな番号(ゲストポートと同じ番号がいいです。既に3306が使用されている場合もあるのでその場合は違う数字に。)、「ゲストポート」に「3306」と入力
<img width="886" alt="スクリーンショット 2020-03-09 16.56.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/a0c642cb-fca6-7af3-7a02-22f5c5ff4cad.png">

4. 「OK」→「OK」で設定画面を閉じてください。

ちなみにゲストポートの「3306」という番号は仮想OSで以下を仮想OSで実行すると確認することができます。

```terminal
$ ss -nlt
State    Recv-Q    Send-Q        Local Address:Port        Peer Address:Port    
LISTEN   0         128           127.0.0.53%lo:53               0.0.0.0:*       
LISTEN   0         5                 127.0.0.1:631              0.0.0.0:*       
LISTEN   0         80                127.0.0.1:3306             0.0.0.0:*       
LISTEN   0         5                     [::1]:631                 [::]:*       
```
ポート番号「3306」は慣例的にmysqlで使用するポート番号のようです。
https://www.fgshop.jp/portno/port3300-4999/

難しい話はいいですね、次にいきましょう。

###bind-addressの変更
ちょっと話が難しいのでまずは手を動かしましょう。
仮想OSの「3306」をホストOSから見れるように設定ファイル`mysqld.cnf`を変更します。

```terminal
$ sudo gedit /etc/mysql/mysql.conf.d/mysqld.cnf
```

開かれたテキストエディタの43行目あたりの`bind-address`と記述されている箇所を以下のように変更。

```text
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address		= 0.0.0.0
```

保存して終了します。
その後mysqlを再起動し、再度`$ ss -nlt`を実行してください。

```terminal
$ sudo systemctl restart mysql
$ ss -nlt
```

先ほどは`127.0.0.1:3306`と書いてあったところが`0.0.0.0:3306`に変更されたでしょうか。
これで設定は完了です。

今やったことが何だったのか気になる人向けに説明すると、「VirtualBoxの設定」の章ではホストOS上のIPアドレス`127.0.0.1:3306`を`10.0.2.15:3306`に変換する、という設定を行いました。
`10.0.2.15`はホストOSから見た仮想OSのIPアドレスを指します。
ただしこれだけではホストOSからゲストOSへと通信は行えません。
(というか自分がやろうとしたらDBeaver上で"Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost."というエラーでアクセスできませんでした。)

`$ ss -nlt`を実行した際に、

- `127.0.0.1:3306`では仮想環境自身のみのポート番号「3306」が通信できる状態を指す
- `0.0.0.0:3306`では仮想環境自身も含め、他のコンピュータからの通信も含め、全てのコンピュータから「3306」へと通信できる状態を指す

であるようで、これによってホストOS→仮想OSの通信が行えたようです。
詳しく知りたい方は自分で調べてみてください。
https://keens.github.io/blog/2016/02/24/bind_addressnoimigayouyakuwakatta/
これを読んでもよく分からなければ飛ばして次へ進みましょう！

###DBeaverで仮想OS上のデータベースを表示
さて、設定も完了したところでDBeaverを起動してみましょう。
起動したら新規接続で仮想環境のデータベースに接続します。
1. 下記の画像の手順で新規接続を行う。
<img width="1446" alt="スクリーンショット 2020-03-09 16.48.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/f777920c-6adc-f2a9-58cc-1446d95e7a67.png">
2. パスワードを入力して「テスト接続」をクリック
<img width="997" alt="スクリーンショット 2020-03-09 17.53.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/6e008942-0c27-fdd4-68b6-e15b1ad0ad5b.png">
3. たぶん「ERROR 1130 (HY000): Host ‘_gateway' is not allowed to connect to this MySQL server」っていうエラーが出ます。
<img width="921" alt="スクリーンショット 2020-03-09 18.17.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/2ef1a2c3-1f87-baad-0ae9-1cacdc4db68d.png">

なので,仮想環境上で`$ mysql -uroot -ppassword`と実行しmysqlを立ち上げ以下を設定。

```sql
mysql> SET GLOBAL validate_password_policy=LOW;
mysql> CREATE USER 'root'@'_gateway' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'_gateway' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
```

4.もう一度「テスト接続」をクリック

これで接続が成功するはずです…！
「_gateway」じゃなくて「gateway」の場合もあるので、その場合は上記のSQLを入力する際、アンダーバーを書かずに実行してください。
DBeaverの具体的な操作は次回、Laracastsの*Section3: Database Access*をやりながら同時に行なっていきます。

#まとめ
データベース周りの環境構築を行なった。
次回はLaracastsの*Section3: Database Access*をやります。
次回: [データベースをLaravelから操作](https://qiita.com/keinko/items/da7609712a3dd6ea082d)