20200414のMySQLに関する記事は8件です。

MySQL5.7 で AUTO_INCREMENT の値が突然 1に戻る怪奇現象を追ってみた。

KT3WlrL_bsg.jpg

実装中に奇妙なことが起きました。
ローカルの開発環境内で構築した MySQL5.7での出来事です。

AUTO_INCREMENTを設定したidを持つテーブルに、INSERT処理を実行しました。
すると、100近くまでカウントされていたidが突然1に戻っていたんです。
そのテーブルは他のテーブルとの関係を多く持っており、これ本番(AWS RDS)もバグっちゃうのでは!?と焦り散らかしましたが、過去そのような事例は起きてなかったみたいなんです。

ガクブルの僕は恐る恐る調査を始めることにしました。

■発生条件の調査

どのタイミングで発生するのだろう。全く予想できない。
約20個近くあるテーブル全てにAUTO_INCREMENTを設定したidが存在するのですが、毎度 1にリセットされてしまうテーブルは決まって1つのテーブルのみ。

何が他のテーブルと違うかなーと考えた時に、1点大きな違いがありました。
それは、 「データ削除の方法」 です。

基本的には「論理削除」を採用しているのですが、とても流動性が高いテーブルだったので、どうやらこのテーブルだけは 「物理削除」 を採用しています。

僕「まさか、、、こいつが関係しているのか?」

いやでも待てよと。何のための AUTO_INCREMENTなんだいと。
その辺を自動で採番してくれるから便利なんだろ AUTO_INCREMENTさんよぉ と。

正直この疑惑は信じたくなかったです。一気にAUTO_INCREMENTの信用が下がってしまうじゃないかと。
でも違いがこれしかないんです。そこで僕はようやく Google先生に力を借り始めました。

■原因究明

検索ワード:mysql autoincrement id リセット

ほとんどが 「AUTO_INCREMENTをリセットする方法」 という検索結果の中、輝く一件を見つけました。

スクリーンショット 2020-04-14 21.44.57.png

僕「ピンポイントすぎるうぅぅぅぅ!!」

真っ白に輝くこちらの記事。僕が求めていた内容が載っていました。

こちらの記事を見てみると、

MySQLが再起動されると連番の一番大きい値にカウンターがリセットされるという実装になっています。
つまり、最大値のレコードが物理削除された後に再起動されると、その値が再度使用されてしまうということです。AUTO INCREMENTカウンターをシーケンスであると完全に信頼して設計していたので、拍子抜けしましたし、実装を理解せずに使用して恥ずかしいです。

、、、嘘でしょ?
信じたくなかったことが起きました。やはり物理削除がAUTO_INCREMENTに大きく関係していました。

再起動をするたびに、AUTO_INCREMENTは連番の最大値にカウンターがリセットされていたんです。
ということは、 もしも物理削除を実施してすっからかんになったテーブルのAUTO_INCREMENTカウンターが「100」だったとしても、MySQLを再起動するとそのテーブルには1件レコードは入っていないので、「1」からスタートしてしまう ということです。

■対策

こちらの記事に掲載されている対策として、3つ紹介がありました。

  1. MySQL8へのバージョンアップ
  2. 論理削除にする
  3. 採番用のテーブルを作る

この3つの中でどれを採用しようかというところなのですが、私が関わっているサービスは、つい先日ローンチしたばかりです。
この初期段階でMySQLのバージョンアップは提案しづらいというのと、まだまだissueが残っているなかで採番用のテーブルを用意して、約20近くのテーブル群の採番を一つにまとめるのも重たいかなと感じました。

そのため、今回はそのテーブルを物理削除から論理削除に切り替えて、その周辺の処理を修正することになりました。(バグも少なそうだし)

■まとめ

  • 新規開発するなら、MySQL8を採用しようね。
  • もしもMySQL5系を採用した新規開発をするなら、AUTO_INCREMENTには十分気をつけて、設計段階でシーケンステーブルを用意しようね。
  • とはいえやっぱり物理削除って本当に怖いから、論理削除を採用しようね。
  • 「まっしろブログ」さんの記事が的確すぎて本当に感謝だね。(以下の参考文献にリンク貼ってますので、そちらも是非)

■追記

書き洩れましたが、なぜ本番環境(AWS RDS)で起きていないかというと、可能性が2点あります。
1. 常に最新の一件が存在した時に再起動が実行されていた。
2. 再起動が実施されなかった。

1 は、神的すぎるタイミングなので、おそらく可能性は薄いかと。
2 は、可能性高いです。
https://go-journey.club/archives/9869
こちらの記事によると、数ヶ月に一回セキュリティパッチの適用があって、自動アップデートが走っちゃうこともあるみたいなのですが、まだそれに当たっていないだけかと。。。
遅かれ早かれ起きていたことなので、ローンチしてすぐ発覚してよかった。。。

■参考文献

https://masshiro.blog/mysql-auto_increment-reset/
https://go-journey.club/archives/9869

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQL 8.0 初期設定

環境

  • Ubuntu 20.04 LTS (Focal Fossa)
  • MySQL 8.0.19

Ubuntu バージョン

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu Focal Fossa (development branch)"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

MySQL インストール

$ sudo apt -y install mysql-server mysql-client
$ mysql --version
mysql  Ver 8.0.19-0ubuntu4 for Linux on x86_64 ((Ubuntu))

MySQL ステータス確認

$ systemctl status mysql
● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2020-03-12 17:03:56 UTC; 1min 9s ago
   Main PID: 24346 (mysqld)
     Status: "Server is operational"
      Tasks: 38 (limit: 1137)
     Memory: 371.9M
     CGroup: /system.slice/mysql.service
             └─24346 /usr/sbin/mysqld

補足: MySQL サービス

# MySQL サービスの起動
$ sudo systemctl start mysql
# MySQL サービスの停止
$ sudo systemctl stop mysql
# MySQL サービスの再起動
$ sudo systemctl restart mysql
# MySQL サービスの自動起動の有効化
$ sudo systemctl enable mysql
# MySQL サービスの自動起動の無効化
$ sudo systemctl disable mysql
# sudo vim /etc/my.cnf
/etc/my.cnf
[mysqld]
character_set_server = utf8mb4 # 文字コード
collation_server = utf8mb4_ja_0900_as_cs # 照合順序

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# Error Log
log-error = /var/log/mysql/mysql-error.log

# Slow Query Log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 5.0
log_queries_not_using_indexes = 0

# General Log
general_log = 1
general_log_file = /var/log/mysql/mysql-query.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

設定ファイルの変更を反映するにはMySQLを再起動する必要があります。

$ sudo systemctl restart mysql

MySQL 初期設定

初期パスワードは今回は secret と入力します。

$ sudo mysql_secure_installation
Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: [空Enter]
Please set the password for root here.

New password: [初期パスワードを入力]

Re-enter new password: [初期パスワードを再度入力]
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

[匿名ユーザーを削除しますか?]
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

[リモートでrootログインを禁止しますか?]
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


[テスト用データベースを削除しますか?]
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

[特権テーブルをリロードしますか?]
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done!

MySQL rootユーザーでログイン

$ sudo mysql -u root -p
  • パスワードはさっき設定した secret
  • rootユーザーでログインするにはsudoが必要
  • exit でMySQLからログアウトできます

MySQL ユーザー一覧

> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| debian-sys-maint | localhost | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | auth_socket           |
+------------------+-----------+-----------------------+

MySQL 文字コード設定

> SHOW VARIABLES LIKE '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

MySQL 照合順序設定

> SHOW VARIABLES LIKE '%collation%';
+-------------------------------+--------------------+
| Variable_name                 | Value              |
+-------------------------------+--------------------+
| collation_connection          | utf8mb4_0900_ai_ci |
| collation_database            | utf8mb4_0900_ai_ci |
| collation_server              | utf8mb4_0900_ai_ci |
| default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci |
+-------------------------------+--------------------+
  • utf8mb4_0900_ai_ci MySQL8.0からの標準
    • 0900 Unicodeのバージョン 9.00
    • ai Accent Insensitiveの略称。アクセントの違いを無視する。
    • 「は」と「ぱ」は等しい文字として評価される。
    • ci Case Insensitiveの略称。大文字と小文字の違いを無視する。
    • 「あ」と「ぁ」は等しいと評価される。

MySQL データベース作成

> CREATE DATABASE shop;

shop という名前のデータベースを作成しています。

ユーザー作成

> CREATE USER phper@'%' IDENTIFIED BY 'secret';

phper@% というユーザーを作成しています。

% ホスト名をワイルドカードで指定しています。
これを設定すると外部からログインできます。
外部アクセスさせたくない場合は、 127.0.0.1localhost を設定します。

権限付与

> GRANT ALL PRIVILEGES on shop.* to phper@'%';
  • shop データベースのすべてのテーブルに対して、特定の権限レベルで使用可能なすべての権限を phper@% ユーザーに設定します。

確認

> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| phper            | %         | caching_sha2_password |
| debian-sys-maint | localhost | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | auth_socket           |
+------------------+-----------+-----------------------+

MySQL 8.0 リファレンスマニュアル

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

③Docker MYSQLにデモデータ(seed_fu)を投入する(2020.4時点)

1.これからDocker導入します、という方は、まず、こちらを見ていただけると幸いです。

①Dockerを初めて導入して基本操作する (2020.4時点)
  https://qiita.com/SakagamiKeisuke/items/4455631886b1c15a3b69

前回までのおさらい 

②Dockerを初めて導入してRails sする (2020.4時点)
  https://qiita.com/SakagamiKeisuke/items/d64ee54c22378223659a

当方、デモデータの投入についてはdb:seed_fuを使用しして開発しております。
Docker環境においてもMYSQLイメージ内にdb:seed_fuでデモデータを投入する作業を進めます。

2.前提

Docker for Macアプリをインストールしている
Dockerサービスが起動している
DockerHubでサインインしている
VSCodeで編集
ターミナル使用
Sequelpro使用(なくてもなんとかなります)

<環境>
macOS : Catalina 10.15.3
Docker version : 19.03.8
ruby : 2.5.1
Rails : 5.2.4.1
MYSQL :5.6

3.DockerコンテナのMYSQLイメージが稼働しているか確認する

”docker-compose up している状態”を保持しつつ、
別ウインドウで新しいターミナルを開いて ローカルのアプリディレクトリに移動(cd)します
(アプリファイルを置いている場所はみなさん違いますので参考です)

ターミナル
 % cd nomadcafe  

Docker ps で起動しているコンテナを調べます。

ターミナル
docker ps

するとこんな感じになります。
image.png
webコンテナとdbコンテナ両方とも STATUS ”Up” になっています。

Dockerのdbコンテナの中に入っていきます。

ターミナル
docker exec -i -t [コンテナID] bash  (カッコは要りません)

dbコンテナのIDを入力します。

ターミナル
 docker exec -i -t ed494a77942a bash

root@ed494a77942a:/# ←これが出てきたら、dbコンテナに入った状態です。

MYSQLにアクセスします。

ターミナル
mysql -u root -p

MYSQLの中のデータベースを一覧表示します。

ターミナル
mysql> show databases;

こんな感じです。
image.png
Mysqlやアプリのdevelopmentやtestがありました!

データベースのうち、nomadcafe_development にアクセスします。

ターミナル
mysql> use nomadcafe_development

Database changed が出ればOKです。

nomadcafe_development のテーブルを一覧表示します。

ターミナル
mysql> SHOW TABLES;

こんな感じです。
image.png
Docker MYSQLイメージにマイグレーションしたテーブルがちゃんと存在していました!

4.Docker環境で、Railsコマンド「rake db:seed_fu」でデモデータを投入する

当方のアプリは、多めのデモデータを投入しておく必要があり「db:seed_fu」を使用しています。

docker-compose.yml にrailsコマンド実行を記述します。

docker-compose.yml
    command: bash -c "bundle exec rake db:seed_fu && /bin/bash"

このへんに書いておきます。(rails sより下に書いたらうまくいきませんでした。)
image.png
この方法が妥当かどうか、正直、理解度が足りずわかりませんが、後々わかれば是正してきます。

docker-compose up --build します。

ターミナル
docker-compose up --build            

localhost:3000にアクセスします。
image.png
無事、each文のボタン表示、dbデータ取得表示ができています。
Showページのdbデータ取得表示もできています。
image.png

5.コンテナのMYSQLにデモデータ投入ができているか確認する

ブラウザでできていることは分かったのですが、念のためdbコンテナのMYSQLを確認します。

ターミナル
docker ps

コンテナIDを調べます。dbコンテナは 794f16c1d24d になります。
image.png
dbコンテナに入ります。

ターミナル
docker exec -it 794f16c1d24d bash

dbコンテナのMYSQLにアクセスします。

ターミナル
mysql -u root -p

こんな感じです。
image.png
データベースを一覧表示します。

ターミナル
mysql> show databases;

image.png
アプリ”nomadcafe_development”のデータベースにアクセスします。

ターミナル
mysql> use nomadcafe_development

Database changed が出たらOKです。

テーブルを一覧表示します。

ターミナル
mysql> SHOW TABLES;

こんな感じです。
image.png

shopsテーブルの中を確認します。

ターミナル
mysql> SELECT * FROM shops;  

image.png
無事、shopテーブルにデモデータが投入されていました!

ですが、日本語が?で表示されてわからない状態になっています。(汗)
ブラウザでは問題なかったので、MYSQL表示の設定ではないかと思われます。

6.DockerのMYSQLイメージを日本語化する

DockerのMYSQL設定を確認します。

ターミナル
mysql> status

こんな感じです。
image.png
latin1とあります、utf8に変えて日本語設定します。

ローカルで「my.cof」ファイルを新規作成し日本語設定の記述をします。

my.conf
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

[client]
default-character-set=utf8

こんな感じです。
image.png
続いて、docker-compose.ymlファイルの、db、volumesを編集します。

ローカルのmy.cnfファイルを DockerのMYSQLイメージの /etc/mysql/conf.d/my.cnfディレクトにマウント(同期)します、という記述です。

docker-compose.yml
  db:
    image: mysql:5.6
    volumes:
      - ./my.cnf:/etc/mysql/conf.d/my.cnf    ←追記します

こんな感じです。
image.png
改めて、起動します。

ターミナル
docker-compose up --build

dbコンテナのMYSQLに入り、データベースのテーブルを確認します。
(同じ手順ですのでコマンドのみ書きます)

ターミナル
docker ps

docker exec -i -t CONTAINER ID bash

 mysql -u root -p

use nomadcafe_development

 SELECT * FROM shops;   

無事、日本語表示が成功しました!
image.png

ちなみに、
SequelProでDockerコンテナのMYSQLイメージに接続すると、簡単にテーブルを確認したり操作できます!
image.png

7.SequelProでDocker MYSQLイメージに接続する

Docker-compose.ymlファイルの設定を見ておきます。
image.png

SequelProを開きアクセスするための入力をします。
・ホストは 「127.0.0.1」 にします
・ユーザー名は 「root」 にしています
・パスワードは 「Docker-compose.ymlで書いたパスワード 」 です
・ポートは 「4306 Docker-compose.ymlで書いた 左側のポート番号」 です

こんな感じです。
image.png
すると、このようにデータベースにアクセスできます!
image.png

8.参考になった記事一覧です。(ありがとうございす!)

【MySQL, SQL】データベースを扱う基本SQL一覧https://qiita.com/knife0125/items/bb095a85d1a5d3c8f706
コマンドはdocker-compose.ymlとDockerfileのどちらで定義するほうがいい?
docker-compose.ymlの書き方について解説してみたhttps://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04
【Rails seedsでdocker起動時に初期データを登録する 。データの重複はfirst_or_createで防ぐ】https://qiita.com/clbcl226/items/a6efd9035e0141251cf1
【Docker】Dockerでホストのディレクトリをマウントするhttps://qiita.com/Yarimizu14/items/52f4859027165a805630
Dockerで立ち上げたMySQLにログインすると日本語が文字化けhttps://qiita.com/luccafort/items/0553c589dcc6459746bc
DockerのMySQLコンテナにSequelProで接続するhttps://qiita.com/y_u_y_a/items/f30019316a1bd738437c

9.最後に

当方、
実務未経験+初学者+テッ○キャンプ卒業+転職活動中であります。
もし、間違い等ございましたらご教示いただけるとありがたいです。

たくさんの先輩方のQiita記事でコードを見合わせできたり、エラー解決記事があったおかげで、ここまで実装できました。
記事を投稿してくださった先輩方に感謝しております。

この先も本番環境でのdocker実装に向けて進みつつ、わかりやすい記事を寄稿していきたいと考えています

ローカル・Dockerで開発環境を整えるまでの続編

④ローカルDocker環境でデータ永続化、entrypointでseed_fuをやり直しする(2020.4.時点)
  https://qiita.com/SakagamiKeisuke/items/8d3fc70a2939cd4bbe3e

こちらも続けて見ていただけると流れがわかると思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

③Docker MYSQLにデモデータ(seed_fu)を投入する!(2020.4時点)

1.これからDocker導入します、という方は、まず、こちらを見ていただけると幸いです。

①Dockerを初めて導入して基本操作する (2020.4時点)
  https://qiita.com/SakagamiKeisuke/items/4455631886b1c15a3b69

前回までのおさらい 

②Dockerを初めて導入してRails sする (2020.4時点)
  https://qiita.com/SakagamiKeisuke/items/d64ee54c22378223659a

当方、デモデータの投入についてはdb:seed_fuを使用しして開発しております。
Docker環境においてもMYSQLイメージ内にdb:seed_fuでデモデータを投入する作業を進めます。

2.前提

Docker for Macアプリをインストールしている
Dockerサービスが起動している
DockerHubでサインインしている
VSCodeで編集
ターミナル使用
Sequelpro使用(なくてもなんとかなります)

<環境>
macOS : Catalina 10.15.3
Docker version : 19.03.8
ruby : 2.5.1
Rails : 5.2.4.1
MYSQL :5.6

3.DockerコンテナのMYSQLイメージが稼働しているか確認する

”docker-compose up している状態”を保持しつつ、
別ウインドウで新しいターミナルを開いて ローカルのアプリディレクトリに移動(cd)します
(アプリファイルを置いている場所はみなさん違いますので参考です)

ターミナル
 % cd nomadcafe  

Docker ps で起動しているコンテナを調べます。

ターミナル
docker ps

するとこんな感じになります。
image.png
webコンテナとdbコンテナ両方とも STATUS ”Up” になっています。

Dockerのdbコンテナの中に入っていきます。

ターミナル
docker exec -i -t [コンテナID] bash  (カッコは要りません)

dbコンテナのIDを入力します。

ターミナル
 docker exec -i -t ed494a77942a bash

root@ed494a77942a:/# ←これが出てきたら、dbコンテナに入った状態です。

MYSQLにアクセスします。

ターミナル
mysql -u root -p

MYSQLの中のデータベースを一覧表示します。

ターミナル
mysql> show databases;

こんな感じです。
image.png
Mysqlやアプリのdevelopmentやtestがありました!

データベースのうち、nomadcafe_development にアクセスします。

ターミナル
mysql> use nomadcafe_development

Database changed が出ればOKです。

nomadcafe_development のテーブルを一覧表示します。

ターミナル
mysql> SHOW TABLES;

こんな感じです。
image.png
Docker MYSQLイメージにマイグレーションしたテーブルがちゃんと存在していました!

4.Docker環境で、Railsコマンド「rake db:seed_fu」でデモデータを投入する

当方のアプリは、多めのデモデータを投入しておく必要があり「db:seed_fu」を使用しています。

docker-compose.yml にrailsコマンド実行を記述します。

docker-compose.yml
    command: bash -c "bundle exec rake db:seed_fu && /bin/bash"

このへんに書いておきます。(rails sより下に書いたらうまくいきませんでした。)
image.png
この方法が妥当かどうか、正直、理解度が足りずわかりませんが、後々わかれば是正してきます。

docker-compose up --build します。

ターミナル
docker-compose up --build            

localhost:3000にアクセスします。
image.png
無事、each文のボタン表示、dbデータ取得表示ができています。
Showページのdbデータ取得表示もできています。
image.png

5.コンテナのMYSQLにデモデータ投入ができているか確認する

ブラウザでできていることは分かったのですが、念のためdbコンテナのMYSQLを確認します。

ターミナル
docker ps

コンテナIDを調べます。dbコンテナは 794f16c1d24d になります。
image.png
dbコンテナに入ります。

ターミナル
docker exec -it 794f16c1d24d bash

dbコンテナのMYSQLにアクセスします。

ターミナル
mysql -u root -p

こんな感じです。
image.png
データベースを一覧表示します。

ターミナル
mysql> show databases;

image.png
アプリ”nomadcafe_development”のデータベースにアクセスします。

ターミナル
mysql> use nomadcafe_development

Database changed が出たらOKです。

テーブルを一覧表示します。

ターミナル
mysql> SHOW TABLES;

こんな感じです。
image.png

shopsテーブルの中を確認します。

ターミナル
mysql> SELECT * FROM shops;  

image.png
無事、shopテーブルにデモデータが投入されていました!

ですが、日本語が?で表示されてわからない状態になっています。(汗)
ブラウザでは問題なかったので、MYSQL表示の設定ではないかと思われます。

6.DockerのMYSQLイメージを日本語化する

DockerのMYSQL設定を確認します。

ターミナル
mysql> status

こんな感じです。
image.png
latin1とあります、utf8に変えて日本語設定します。

ローカルで「my.cof」ファイルを新規作成し日本語設定の記述をします。

my.conf
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

[client]
default-character-set=utf8

こんな感じです。
image.png
続いて、docker-compose.ymlファイルの、db、volumesを編集します。

ローカルのmy.cnfファイルを DockerのMYSQLイメージの /etc/mysql/conf.d/my.cnfディレクトにマウント(同期)します、という記述です。

docker-compose.yml
  db:
    image: mysql:5.6
    volumes:
      - ./my.cnf:/etc/mysql/conf.d/my.cnf    ←追記します

こんな感じです。
image.png
改めて、起動します。

ターミナル
docker-compose up --build

dbコンテナのMYSQLに入り、データベースのテーブルを確認します。
(同じ手順ですのでコマンドのみ書きます)

ターミナル
docker ps

docker exec -i -t CONTAINER ID bash

 mysql -u root -p

use nomadcafe_development

 SELECT * FROM shops;   

無事、日本語表示が成功しました!
image.png

ちなみに、
SequelProでDockerコンテナのMYSQLイメージに接続すると、簡単にテーブルを確認したり操作できます!
image.png

7.SequelProでDocker MYSQLイメージに接続する

Docker-compose.ymlファイルの設定を見ておきます。
image.png

SequelProを開きアクセスするための入力をします。
・ホストは 「127.0.0.1」 にします
・ユーザー名は 「root」 にしています
・パスワードは 「Docker-compose.ymlで書いたパスワード 」 です
・ポートは 「4306 Docker-compose.ymlで書いた 左側のポート番号」 です

こんな感じです。
image.png
すると、このようにデータベースにアクセスできます!
image.png

8.参考になった記事一覧です。(ありがとうございす!)

【MySQL, SQL】データベースを扱う基本SQL一覧https://qiita.com/knife0125/items/bb095a85d1a5d3c8f706
コマンドはdocker-compose.ymlとDockerfileのどちらで定義するほうがいい?
docker-compose.ymlの書き方について解説してみたhttps://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04
【Rails seedsでdocker起動時に初期データを登録する 。データの重複はfirst_or_createで防ぐ】https://qiita.com/clbcl226/items/a6efd9035e0141251cf1
【Docker】Dockerでホストのディレクトリをマウントするhttps://qiita.com/Yarimizu14/items/52f4859027165a805630
Dockerで立ち上げたMySQLにログインすると日本語が文字化けhttps://qiita.com/luccafort/items/0553c589dcc6459746bc
DockerのMySQLコンテナにSequelProで接続するhttps://qiita.com/y_u_y_a/items/f30019316a1bd738437c

9.最後に

当方、
実務未経験+初学者+テッ○キャンプ卒業+転職活動中であります。
もし、間違い等ございましたらご教示いただけるとありがたいです。

たくさんの先輩方のQiita記事でコードを見合わせできたり、エラー解決記事があったおかげで、ここまで実装できました。
記事を投稿してくださった先輩方に感謝しております。

この先も本番環境でのdocker実装に向けて進みつつ、わかりやすい記事を寄稿していきたいと考えています

ローカル・Dockerで開発環境を整えるまでの続編

④ローカルDocker環境でデータ永続化、entrypointでseed_fuをやり直しする(2020.4.時点)
  https://qiita.com/SakagamiKeisuke/items/8d3fc70a2939cd4bbe3e

こちらも続けて見ていただけると流れがわかると思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【SQL】SQLコマンド入門

はじめに

学習中の備忘録です。

概要

  • データベースの表示・選択
  • データの登録・更新・削除

前提

MYSQL

データベースの表示・選択

mysqlに接続

ターミナル
% mysql -u root

ターミナル表示
9f2a7f2e005c30dc50d3f50f2a84ff73.png

データベース一覧を表示

SHOW DATABASES;
ターミナル
mysql> SHOW DATABASES;

ターミナル表示
61ee7bb56e6c9c19f86316276ab8ded2.png

データベース選択

USE データベース名;

画像にはありませんがmy_hobby_app_developmentというデータベースを選択します。

ターミナル
mysql> USE my_hobby_app_development;

ターミナル表示
4a099ecd284862d872bc925fa64cb25d.png

テーブルを表示

SHOW TABLES;
ターミナル
mysql> SHOW TABLES;

ターミナル表示
fe9bd1c78cc643c5036b45f34e24d095.png

カラムを表示

SHOW columns FROM テーブル名;

postsテーブルのカラムを表示します。

ターミナル
mysql> SHOW columns FROM posts;

ターミナル表示
dcca8a02de58d5ea7edd834100de8c82.png

データの登録・更新・削除

ALTER TABLE文

カラムの追加・修正・削除はすべてテーブル構造の変更です。
そのためSQL文は共通して、ALTER命令を用いたALTER TABLE文を使用します。
実行時は以下のような文法で使用します。

ALTER TABLE テーブル名 操作

データの登録

型名 保存できる値
INT 数字
VARCHAR(M) 最大M文字の文字列

カラムを1つだけ追加する場合

ALTER TABLE テーブル名 ADD カラム名 カラムの型;

カラムを複数追加する場合

ALTER TABLE テーブル名 ADD (カラム名 カラムの型, ……);

postsテーブルにnumカラムをint型で追加

ターミナル
mysql> ALTER TABLE posts ADD num int;

ターミナル表示
b35777ea94fee9776dc7183ad045715f.png

データの更新

ALTER TABLE テーブル名 CHANGE 古いカラム名 新しいカラム名 新しいカラムの型;

numカラムをnumberカラムに更新

ターミナル
mysql> ALTER TABLE posts CHANGE num number int;

ターミナル表示
c85117cc6d75f3083d7a9cf4d921dee9.png

データの削除

ALTER TABLE テーブル名 DROP カラム名;

postsテーブルのnumberカラムを削除

ターミナル
mysql> ALTER TABLE posts DROP number;

ターミナル表示
ee8ebf9710a93d4a3bd6a3d09c74ba48.png

まとめ

Railsでアプリケーション作成してる段階ではあまり登場しませんが、適宜追記するかもです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS EC2でサーバを構築 5 - MySQL + phpMyAdmin

記事一覧

概要

Amazon Linux 2を含むRHEL (RedHat Enterprise Linux) 系のOSでは、MySQLから派生したMariaDBがデフォルトで採用されています。これについての経緯は省きますが、Oracleによる買収後も従来通りに利用可能であるため、互換性重視でMySQLを採用します。

MySQLはサーバリソースを食うため、アクセス数や負荷が増えたらRDSへのリプレースも検討した方が良いでしょう。

MySQL

デフォルトのキャラセットを変更します。

今回、特にパフォーマンスチューニングは行いません。

/etc/my.cnf

character-set-server = utf8

以下は最初に行う儀式的なコマンドです。root@localhostのパスワードを変更します。

mysql_secure_installation

MySQLを停止します。

systemctl stop mysqld

デフォルトでは難解なパスワードしか認められずエラーになるのでこれを回避する設定です。

mysql -u root -p

> set global validate_password_policy=LOW;
> quit

改めてMySQLを起動します。

systemctl start mysqld

phpMyAdmin

設定ファイルのサンプルをコピーして設定ファイルを作成します。

cd /var/www/html/www.example1.com/public_html/phpmyadmin
cp config.sample.inc.php config.inc.php

/var/www/html/dev.netartz.com/public_html/config.inc.php

phpMyAdminはすぐにセッションが切れてしまい再ログインが手間なので、セッションが24時間持続するようにします。

$cfg['blowfish_secret'] = '{記号を含む長いランダムな文字列}'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

$cfg['LoginCookieValidity'] = 86400;

phpMyAdminにログインしてphpmyadminデータベースを作成し、SQL文をインポートします。

mysql -uroot -p phpmyadmin < ./sql/create_tables.sql
mkdir tmp
chmod 777 tmp
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golang - MySQL Scan Error

Problem

sql: Scan error on column index 5, name \"time\": unsupported Scan, storing driver.Value type []uint8 into type *time.Time]"}

Solution

You need added string "parseTime=true" in mysql connection setting.

db, err := sql.Open("mysql", "root:@/?parseTime=true")

https://stackoverflow.com/questions/29341590/how-to-parse-time-from-database/29343013#29343013
https://stackoverflow.com/questions/45040319/unsupported-scan-storing-driver-value-type-uint8-into-type-time-time

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

返信機能実装時、工夫した点 -newアクション-

投稿に対する返信機能を作成する際に、newアクションの実装を少し工夫することで便利にすることができました。

●実装コード

Q&Aサイトを実装しているため、投稿=Question 返信=Answerとなっています。

app/contorollers/answers_controlelr.rb
  def new
    @question = Question.find(params[:id])
    @answer = @question.answers.build
  end
config/routes.rb
  get  "/answers/:id", to: "answers#new", as: :new_answer
  resources :answers, except: %i(new)

●解説

1.アソシエーションでquestionを取得することができる。

app/contorollers/answers_controlelr.rb
  def new
    @question = Question.find(params[:id])
    @answer = @question.answers.build
  end

こうすることで、@answer = @question.answersとすることで、@answer.questionのような形で、questionを取得することができます。例えば下記のように活用したり。

app/contorollers/answers_controlelr.rb
def create
redirect_to question_path(@answer.question)

2.@questionを取得することで、"answers/new" ページに質問の内容を記載することができる。

get  "/answers/:id", to: "answers#new", as: :new_answer
  resources :answers, except: %i(new)

こうすることで、/new/:question_id とすることができます。
この記述がないと、/new.question_id となってしまい、パラメーターを渡すことができません。

●まとめ

あくまで自分はポートフォリオを作成している段階のレベル感です。
もっと良い実装方法や誤りがありましたら、指摘して頂けますと大変助かります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む