Nuxt と Go で Software Architecture の実験 ~3日目 MySql編~

## はじめに

今回も[@Sekky0905Ks](https://twitter.com/Sekky0905Ks)さんのコミットを遡らせていただき、使われている技術一つ一つをまとめさせていただきました。

サーバーサイドは勉強中の身なので間違い等ありましたらご報告いただけると嬉しいです。それでは始めていきましょう。

## Mysqlのセットアップ

Dockerコンテナ上にMysqlをセットアップしていきたいと思います。まず最初に```mysql/my.cnf```を作成しましょう。

```cnf:mysql/my.cnf
[mysqld] # Setting for mysql server.
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci # Ignore lower/upper case of alphabet. 


[client] # Setting for mysql client tool.
default-character-set=utf8mb4
```

次に、```mysql/init/setup.sql```上に、初期状態のデータベースとテーブルを作成するためのコードを記述します。InnoDBについて興味がある方は[知って得するInnoDBセカンダリインデックス活用術！](https://nippondanji.blogspot.com/2010/10/innodb.html)もどうぞ。

```sql:mysql/init/setup.sql
USE  nuxt_go_template;

/*
Create users table. It has 'id' which has a unique identity, 
'name' with the length of 30 characters, 'session' id with the 
length of 36 characters, 'password' with the length of 64 characters,
created time and updated time. Primary key is 'id'.
*/
CREATE TABLE IF NOT EXISTS users (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(30) NOT NULL,
    session_id VARCHAR(36) NOT NULL,
    password VARCHAR(64) NOT NULL,
    created_at DATETIME DEFAULT NULL,
    updated_at DATETIME DEFAULT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

/*
Create sessions table. It has 'id' with the length 
of 36 characters, 'user id', created time, and 
updated time. Primary key is 'id'.
*/
CREATE TABLE IF NOT EXISTS sessions (
    id VARCHAR(36) NOT NULL,
    user_id INT UNSIGNED NOT NULL,
    created_at DATETIME DEFAULT NULL,
    updated_at DATETIME DEFAULT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*
Create threads table. It has 'id' which has
a unique identity, 'time' with the length of 
20 characters, user id and created time, 
updated time. Primary key is 'id'.
*/
CREATE TABLE IF NOT EXISTS threads (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    title VARCHAR(20) NOT NULL,
    user_id INT UNSIGNED NOT NULL,
    created_at DATETIME DEFAULT NULL,
    updated_at DATETIME DEFAULT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY (title)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*
Create comments. It has 'id' which has unique 
character, thread id, user id, content with the 
length of 200 characters, created time, and 
updated time. Primary key is 'id'.
*/
CREATE TABLE IF NOT EXISTS comments (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    thread_id INT UNSIGNED NOT NULL,
    user_id INT UNSIGNED NOT NULL,
    content VARCHAR(200) NOT NULL,
    created_at DATETIME DEFAULT NULL,
    updated_at DATETIME DEFAULT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

```

Dockerの設定に関しては、```docker-compose.yaml```に```nvgdb```イメージを作成していきます。
MySQL8.0より認証方式が変わったので、[DockerでMySQL8.0の環境構築 & 認証方式変更](https://www.wakuwakubank.com/posts/596-mysql-8-with-docker/)を参考にしつつ、パスワードを用いた認証方法に変更すると、sequel-proなどのGUIツールからDockerコンテナ内で起動したMySQLサーバにアクセスすることができます。

volumesの部分で行っている永続化に関しては[docker-compose＋MySQL5.7(8.0も)+初期化+永続化](https://qiita.com/juhn/items/274e44ee80354a39d872)を参考にしていただけるとわかりやすいかと思います。


```yaml:docker-compose.yaml
version: '3'

services:
  nvgdb:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_DATABASE: "nuxt_go_template"
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
    volumes:
      - "./mysql:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    container_name: gvdb
    ports:
      - "3306:3306"
  app:
    build:
      context: ./
      dockerfile: docker/Dockerfile
    volumes:
      - ./:/go/src/github.com/hideUW/nuxt_go_template
    command: bash -c 'cd /go/src/github.com/hideUW/nuxt_go_template/server && go run *.go'
    ports:
      - "8080:8080"
    container_name: app
```

## 動いているかどうか確認する

```docker-compose start```でコンテナを立ち上げ、MySQlサーバーが立ち上がっているか、実際にデータベースが初期化されているかを確認します。

ターミナルからDockerコンテナ内のMySQLサーバにアクセスします。

```shell
$ mysql -u root -p -h 127.0.0.1 -P 3306
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182922/400803dd-941e-533f-8d69-597cc96dfc59.png)

以上の画像より、無事サーバの立ち上げと初期化が行われていることを確認しました。


## 参考
[@Sekky0905Ks](https://twitter.com/Sekky0905Ks)さん - [nuxt-vue-go-chat](https://github.com/sekky0905/nuxt-vue-go-chat/commits/master)
Chris Chuck - [How to Create a MySql Instance with Docker Compose](https://medium.com/@chrischuck35/how-to-create-a-mysql-instance-with-docker-compose-1598f3cc1bee)