- 投稿日:2020-02-11T20:47:29+09:00
[MySQL]インデックス�と索引の違いについて
この投稿の経緯
インデックスはDBの初学者に、「索引」という2文字で説明されることが多い。
私も、その説明で何となく理解したつもりになっていたが、よくよく考えてみると「索引」ではインデックスを正確に理解することはできない気がしてきた(無知の知)。
「索引」と「インデックス」の2つを比較しながら頭の整理をしたメモ書き的な内容です。
認識が違っていましたら、コメントお待ちしております。
ここでは本の索引は「索引」、DBのインデックスは「インデックス」と呼びます。索引
索引とは
引用元
https://www.weblio.jp/content/%E3%81%95%E3%81%8F%E3%81%84%E3%82%93ある書物に載っている項目・人名・用語などを書き出して五十音順などに並べ、その所在ページなどを示した表。インデックス。
- 本でいうページにあたるものが主キー
- 索引の項目は1項目単位で表現
「大陸の生態系」みたいな本の索引のイメージです
インデックス
インデックスとは
- インデックスの種類
- インデックスのない状態: ページの順番がバラバラな本でしょうか?
- クラスタインデックス: 本自身(「キー:ページ、値:本文」、一意のキーが連番で昇順に並んでいる)です
- セカンダリインデックス: 索引です ※ALTERで作成するインデックスはこちらのことです
- 単一列インデックス
- 本の索引に近い(1項目単位の項目と該当する主キー(ページ)だけを持っている)のはこっち
- カバリングインデックス 本の索引とは異なる(複数項目を組み合わせた単位の項目と該当する主キー(ページ)及び取得するべき全ての値を持っている)
- 複合インデックス(予め組み合わせを作っておく)
- インデックスマージ(複数の単一列インデックスがクエリ実行の際に合体、オーバーヘッドあり)
continentテーブルです
カバリングインデックスの定義だとこうなります
alter table continent add index (name, animal, fruit);
まとめ
索引は項目一つに対して一つまたは、複数のページを参照させるもの。
インデックスは、項目一つまたは、複数の項目の組み合わせに対して一つの主キーを参照させるもの。インデックスについて調べるとクラスタインデックスとセカンダリインデックスを明示することなく単にインデックスと記載している記事、参考書が多くそこを理解するのに結構苦労しました。
インデックスが効いている言われるときのインデックスはセカンダリインデックスです。
セカンダリの中でもカバリングインデックスは取得項目を全てセカンダリインデックスのリーフブロックに保持しているので、わざわざクラスタインデックスを見に行かなくてよいので検索件数が減り検索が早いです。
索引で例えるなら、索引を見れば本文の内容までわかってしまうといったことでしょうか?
ちなみにフルインデックススキャンとはクラスタインデックスを全て見てるので検索が遅いです。この様に頭をインデックスと索引の違いを整理すると、「索引」という例えは結構無理があるのかなと思いました。
とはいえ、「索引」の例えは良いアプローチだと思いますので、人に説明するときは、誤解の内容に「索引」という例えを使っていこうと思います。
- 投稿日:2020-02-11T20:47:29+09:00
[MySQL]インデックス�と本の索引の違いについて
この投稿の経緯
インデックスはDBの初学者に、本の「索引」という2文字で説明されることが多い。
私も、その説明で何となく理解したつもりになっていたが、よくよく考えてみると「索引」ではインデックスを正確に理解することはできない気がしてきた(無知の知)。
「索引」と「インデックス」の2つを比較しながら頭の整理をしたメモ書き的な内容です。
認識が違っていましたら、コメントお待ちしております。
ここでは本の索引は「索引」、DBのインデックスは「インデックス」と呼びます。索引
索引とは
引用元
https://www.weblio.jp/content/%E3%81%95%E3%81%8F%E3%81%84%E3%82%93ある書物に載っている項目・人名・用語などを書き出して五十音順などに並べ、その所在ページなどを示した表。インデックス。
- 本でいうページにあたるものが主キー
- 索引の項目は1項目単位で表現
「大陸の生態系」みたいな本の索引のイメージです
インデックス
インデックスとは
- インデックスの種類
- インデックスのない状態: ページの順番がバラバラな本でしょうか?
- クラスタインデックス: 本自身(「キー:ページ、値:本文」、一意のキーが連番で昇順に並んでいる)です
- セカンダリインデックス: 索引です ※ALTERで作成するインデックスはこちらのことです
- 単一列インデックス
- 本の索引に近い(1項目単位の項目と該当する主キー(ページ)だけを持っている)のはこっち
- カバリングインデックス 本の索引とは異なる(複数項目を組み合わせた単位の項目と該当する主キー(ページ)及び取得するべき全ての値を持っている)
- 複合インデックス(予め組み合わせを作っておく)
- インデックスマージ(複数の単一列インデックスがクエリ実行の際に合体、オーバーヘッドあり)
continentテーブルです
カバリングインデックスの定義だとこうなります
alter table continent add index (name, animal, fruit);
まとめ
索引は項目一つに対して一つまたは、複数のページを参照させるもの。
インデックスは、項目一つまたは、複数の項目の組み合わせに対して一つの主キーを参照させるもの。インデックスについて調べるとクラスタインデックスとセカンダリインデックスを明示することなく単にインデックスと記載している記事、参考書が多くそこを理解するのに結構苦労しました。
インデックスが効いている言われるときのインデックスはセカンダリインデックスです。
セカンダリの中でもカバリングインデックスは取得項目を全てセカンダリインデックスのリーフブロックに保持しているので、わざわざクラスタインデックスを見に行かなくてよいので検索件数が減り検索が早いです。
索引で例えるなら、索引を見れば本文の内容までわかってしまうといったことでしょうか?
ちなみにフルインデックススキャンとはクラスタインデックスセカンダリインデックスのリーフブロックを全て見てるので検索が遅いです。この様に頭をインデックスと索引の違いを整理すると、「索引」という例えは結構無理があるのかなと思いました。
とはいえ、「索引」の例えは良いアプローチだと思いますので、人に説明するときは、誤解の内容に「索引」という例えを使っていこうと思います。
- 投稿日:2020-02-11T19:09:04+09:00
Sequel Proがクラッシュ(?)した件
Sequel Proがこの画面から進まなくなりました。
一応、自分なりに公式ドキュメントや、キータを読み漁りましたが解決することができませんでした。
どうしたか
macを初期化し、新しくSequel Proを入れ直しました。(あまり良い方法ではないと思いますが。)
その後、生まれ変わったmacbookにslackやらGithubやらを入れ、問題のSequel Proも入れました。
すると普通にソケット接続がされて、データベースを選択できるようになりました。
なぜこうなったのか
考えられる原因としてはエラーを解決しようとする中で、何度もmysqlのインストール・アンインストールを繰り返したことだと思います。
またはSequel Proのタブを閉じ、再び起動すると毎回のごとく「アプリが予期せぬ終了の仕方をしました」のような文が表示されていたことも原因の一つかなと思います。まとめ
エラーを解決するときにターミナルに打ち込んだコマンドが、思わぬエラーを引き起こすことがあるかもしれないので、エラー解決は慎重に行う必要があるなと感じました。
- 投稿日:2020-02-11T18:25:54+09:00
MacBookの環境 mysql5.6からmysql8.0に更新
やったこと
どこかで、rails6 色々変わりすぎてヤバイ!笑
っていう話を耳にして、そういえば開発環境に関してはスクールから言われるままに特定のバージョンを入れただけだな〜と思い確認すると案の定、古い安定バージョンを入れていた。自分は金がかからない限りは無駄に冒険してしまうところがあるので、Rails、Ruby、Mysqlをバージョンアップさせようと思いついてしまった。ちなみにちなみに、自分は少数派のキチンとバックアップタイプですが、timemachineで外付けHDDにバックアップがある為、いつでも戻れる!という安心感の中でやりました。
新旧バージョン
app 旧 新 Ruby 2.5.1 2.6.5 Rails 5.2.3 6.0.2.1 Mysql 5.6 8.0 ※Rubyに関しては、最新2.7.0にしてしまうと、対応しているgemが少なくなってしまう為開発に甚大なダメージが・・・ということで、その前のバージョンで我慢しておく事にした。
RubyとRails
Homebrewをアップデートして、
- 最新バージョンをダウンロードしてきて、
- 最新バージョンをインストールして、
- 最新バージョンをデフォルト指定した。
Railsは旧バージョンをアンインストールしたかもしれない。Rubyはインストールしたバージョンを残しておけるみたい(brew??)。
実行したコマンドは忘れた。けど大して苦労はしてないハズ。
Rubyだけ、最新2.7.0にした時に既存アプリをrails startした時にエラーがいっぱい出てきて、それらのエラーはgemが未対応な事によるエラーだよ、っていう記事を見つけて考え直して2.6.5を入れたぐらい。
時刻設定
色々やって手順が前後する(Mysqlの設定にも関わる)が、まずRailsからMysql使ってた時に自動保存される時刻情報が無茶ずれてる(UTC時刻になってる)事が気に入らなかった。これに関してはRailsアプリを使っている時にRailsのプログラム内で日本時間に直すようなことをやっていたが、結局のところMysql自体にはUTC時間のまま保存されていたので、それを分かりやすく日本時間にしたかった。
デスクトップから右上に見える時刻表示(正常に日本時間表示)を気にしながら、コマンドラインでDateコマンドを打ってみると、なぜかUTC時刻になっていた。ひょっとしたらMacBookPro2017のデフォルトではJSTになっていたのかもしれないが、色々触りまくったので定かではない・・・
ということで、まずはシステム時間の修正から
システム時間(OS)
色々と調べた結果、システム時間の設定は /etc/localtime のバイナリファイルらしい。
更に、日本時間他各国のtimezone設定は /usr/share/zoneinfo/ にバイナリファイルがあり、日本時間の設定は /usr/share/zoneinfo/Japan のバイナリファイルらしい。色々調べてたら、 /usr/share/zoneinfo/Asia/Tokyo っていう情報がいっぱい出てきたので必死にAsiaフォルダの中を探してたヨ。
$ sudo ln -s /usr/share/zoneinfo/Japan /etc/localtime でdateコマンドがJSTで表示されるようになる。 ※一般的にこういう操作する時は、 /etc/localtimeのバイナリファイルをバックアップとっておくらしい。自分はtimemachineでシステムバックアップとってるので気にしなかった。んで、あ〜安心と油断してたらデスクトップ右上の時間がこれまたメチャずれてた。なんでやねん、と思いながら "日付と時刻"環境設定を開く から時刻修正。
日付と時刻は、「日付と時刻を自動的に設定」にチェックを入れて、appleアジア(time.asia.apple.com)を選択。
時間帯は、「現在の位置情報に基づいて、時間帯を自動的に設定」のチェックを外してエリア選択で「日本」を設定した。これで直ればいいが、すぐに時刻が設定されなかったので、なんとなくMACを再起動。
なんとか、デスクトップ右上の時刻も正常になった。Mysql
時刻設定した後に、mysqlの時刻設定を見てみたらキチンと日本時間が適用されていた。
mysql> show variables like '%time_zone%'; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | JST | | time_zone | SYSTEM | +------------------+--------+ 2 rows in set (0.02 sec)Mysqlはバージョン共存する方法もあるらしいが、自分は旧の方はアンインストールした。
順に
旧をバックアップ、
旧をアンインストール、
(一応)再起動、
新をインストール、
my.cnf設定、
バックアップをリストアバックアップ(エクスポート)
※後述するが、Mysql8.0に移行させる為にこの時のバックアップファイル(.sql)を編集するので、mysqldumpコマンドのオプションでなんとかできるならば、その方が楽。
$ mysqldump --single-transaction -u root -p -x --all-databases > 出力ファイル名でいけるハズだけど、一時期うまく実行できなかった。
どういうコマンドで見たのか覚えていないが、データベースのプロパティをみる方法があり、--all-databases がFALSEになっていた。原因はよくわからないが、どこかの時点から --all-databasesができるようになっていた。よく分からん。とりあえず、コマンド実行後に何も表示されないので、ちゃんと中身にクエリが入っているかは見ておいた方がいい
旧をアンインストール
単純な話、 brew uninstall mysql@5.6 を実行すればいいがゴミが残ってしまった事で何度もインストールを繰り返したので、きちっときれいにした方がいい。
$ brew uninstall mysql@5.6どうしよう!困った時のMac上のMySQLのアンインストール&再インストール、動作確認手順
これの「Community Editionを削除する」「brew で入れたものを削除する」は何度やったか分からんぐらいやった。内容的に、「Community Editionを削除する」はやらんでいいかもしれんが、一応。
更にまた一応、Macを再起動。
インストール
// homebrewをアップデート $ brew update // インストールできるmysqlのバージョン確認 $ brew infomysql // インストール $ brew install mysqlmy.cnf設定
ファイルの場所は覚えられないのに、my.cnfの候補ディレクトリを探すコマンドだけ覚えた
$ mysql --help | grep my.cnf order of preference, my.cnf, $MYSQL_TCP_PORT, /etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnfこの内、自分は /usr/local/etc/my.cnfを使った。なぜなら4か所の内、そこにだけデフォルトでファイルがあったから。
/usr/local/etc/my.cnf# Default Homebrew MySQL server config [mysqld] # Only allow connections from localhost bind-address = 127.0.0.1 mysqlx-bind-address = 127.0.0.1 character-set-server=utf8 default_authentication_plugin=mysql_native_password skip-slave-start log_timestamps=SYSTEMmysqlx-bind-address = 127.0.0.1
まではデフォルトで入力されてるので触らないようにする。character-set-server=utf8
mysqlで日本語入力を可能にするdefault_authentication_plugin=mysql_native_password
Mysql8.0からユーザー認証方法のデフォルトがcaching_sha2_passwordになってるらしい。これをやっておかないと多分うまくインポートできないし、Railsなんかに影響出そう。skip-slave-start
なんかMysqlのログにエラー表示されてたので入れたが、結局ログにはエラーが残り続けてるのでよく分からない。入れなくてもいいかもしれない。Mysqlのバックアップをとる設定らしい。それを無視する。log_timestamps=SYSTEM
Mysqlに保存されるログの時刻がこれまたUTCになっていたので日本時間にする為の設定。ちなみにログファイルは、/usr/local/var/mysql/マシン名.local.err にある。インポートの前にユーザーの認証方式を変更
ここを参考に、pluginの部分を全部mysql_native_passwordに。
ひょっとするとrootだけでいいかもしれない。変え終わった後に他のコマンドを打とうとすると、確か警告が出てきてた。パスワードを設定しなさい、という。一旦適当なパスワードを設定して他のコマンドを実行できることを確認した上で、またパスワード無しを設定したが、いきなりパスワード無しでもいいかもしれない。
mysql> ALTER USER 'root'@'localhost' identified BY 'hoge'; mysql> ALTER USER 'root'@'localhost' identified BY '';インポートの前にファイル修正
エクスポートの段階でとったバックアップファイルを三段階で修正(部分削除)した。
vi操作を調べとかないと厳しい。特に行削除操作。innodbに関する部分を削除
どこを見たのだったか忘れてしまった。。。これかな?
AWS Auroraでダンプしたデータをmysqlにインポートしようとしたらはまった$ vi 保存したログファイル名.sql削除した部分は、
-- Table structure for table`innodb_index_stats`
-- Dumping data for table`innodb_index_stats`
-- Table structure for table`innodb_table_stats`
-- Dumping data for table`innodb_table_stats`
の部分。columns_privに関する部分を削除
これがさっきのページの情報だったか・・・
AWS Auroraでダンプしたデータをmysqlにインポートしようとしたらはまった削除した部分は
-- Table structure for table`columns_priv`
-- Dumping data for table`columns_priv`
の部分。mysqlデータベースのuserテーブルに関する部分を削除
これのヒントは、ユーザー認証の部分を説明してくれてたページ。
削除した部分は
-- Table structure for table`user`
-- Dumping data for table`user`
バックアップデータの修正は以上。
:w 一応別名で保存.sql :q!バックアップをインポート
さっき保存したファイルを読み込み
$ mysql -uroot < 一応別名で保存.sqlこれで、最新バージョンが使えるハズだけど、railsアプリを起動して問題なくMysqlが動くか確認しておくと安心。
Sequel Proが・・・
どういうわけか、Mysql8.0ではSequel Proが使えなくなるのでテストビルド版をインストールしないといけない・・・
- 投稿日:2020-02-11T15:36:22+09:00
Macのhomebrewでmysqlクライアントのみインストールする
Macのローカルに作った開発環境のmysqlに接続はしたいけどサーバーはインストールしたくなかったのでメモ
homebrewの確認
homebrewはインストール済みであることが前提です
$ brew -v Homebrew 2.2.2 Homebrew/homebrew-core (git revision fdb53; last commit 2020-01-03) Homebrew/homebrew-cask (git revision d9c8; last commit 2020-01-03)mysql確認
$ mysql --version -bash: mysql: command not found入ってません。
インストール
brew install mysql --client-only ... Error: invalid option: --client-onlyあれ、エラーになってしまうようですね。どうやらこのコマンドだと私の環境ではインストールできないようです。
以下のコマンドでインストール出来ました。
brew install mysql-client
インストールできました。
... ######################################################################## 100.0% ==> Pouring mysql-client-8.0.18.high_sierra.bottle.tar.gz ==> Caveats mysql-client is keg-only, which means it was not symlinked into /usr/local, because it conflicts with mysql (which contains client libraries). If you need to have mysql-client first in your PATH run: echo 'export PATH="/usr/local/opt/mysql-client/bin:$PATH"' >> ~/.bash_profile For compilers to find mysql-client you may need to set: export LDFLAGS="-L/usr/local/opt/mysql-client/lib" export CPPFLAGS="-I/usr/local/opt/mysql-client/include"パスを通す
ログにもありますが、パスを通さないと、「mysql」コマンドで呼び出せないようです。
$ mysql --version -bash: mysql: command not found以下のように.bash_profileに書き込んで、sourceコマンドで即時反映させればOKです。
$ echo 'export PATH="/usr/local/opt/mysql-client/bin:$PATH"' >> ~/.bash_profile $ source ~/.bash_profile確認
$ mysql --version mysql Ver 8.0.18 for osx10.13 on x86_64 (Homebrew)おつかれさまでした。
- 投稿日:2020-02-11T14:47:25+09:00
MySQL Access denied for user 'root'@'localhost' の対応
MySQLでエラーが出てハマったのでその対応。
まずは権限なしで立ち上げられるように設定
$ mysqld_safe --skip-grant-tables & [1] 11541 2020-02-11T04:59:48.6NZ mysqld_safe Logging to '/usr/local/var/mysql/*** 2020-02-11T04:59:48.6NZ mysqld_safe Starting mysqld daemon with databases from /usr/local/var/mysqlMySQLにログイン
$ mysql -u root
root@localhost
のユーザーを一旦削除してから作り直し、全ての権限を与える。mysql> DROP USER root@localhost; Query OK, 0 rows affected (0.01 sec) mysql> CREATE USER 'root'@'localhost' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.01 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost'; Query OK, 0 rows affected (0.00 sec)その後、下記コマンドを打つとパスワードを求められるので、パスワードを入れてログインできればOK!
$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g.
- 投稿日:2020-02-11T14:32:04+09:00
docker-composeでLaravel環境構築
はじめに
dockerによってLaravelの環境構築を行います。laradockは使いません。
以前はlaradockを使っていましたが、
・プロジェクトが必要以上に大きくなる
・dockerの知識がほとんどなくても環境構築できでしまう
これらの点からlaradockを使わない方法を試していきます。laradockはとりあえずdockerでLaravelを立ち上げたい方、知識が全くない方は使うとよいかもしれません。
以前にlaradockによるlaravelの環境構築の記事を書きましたので、laradockを使いたい方はこちらを→https://qiita.com/rope19181/items/da31dc2cd6097315fa10
環境・仕様
・nginx上でPHP実行環境を構築し、Laravel新規プロジェクト作成。
・mysqlとwebGUIとしてphpmyadminも使えるようにします。環境、仕様は以下の通りです。
Docker version 19.03.5
docker-compose version 1.24.1
php 7.2-fpm
mysql 5.7構成
最終的にこのような構成となります。
project
├ docker
│ ├ db
│ │ ├ data
│ │ ├ my.conf
│ │ └ sql
│ │
│ ├ nginx
│ │ └ default.conf
│ │
│ └ php
│ ├ Dockerfile
│ └ php.ini
├ myapp
└ docker-compose.yml今回はprojectをルートディレクトリとしています。
./myapp
はlaravelのプロジェクトを置くディレクトリとなります。docker-compose.ymlの作成
docker-composeでは複数のコンテナを管理、構築するためにdocker-compose.ymlに各コンテナの環境設定を定義します。
docker-compose.ymlversion: '3' services: php: container_name: php build: ./docker/php volumes: - ./myapp/:/var/www nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./myapp/:/var/www - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php db: image: mysql:5.7 container_name: db-host environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: database MYSQL_USER: docker MYSQL_PASSWORD: docker TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - ./docker/db/data:/var/lib/mysql - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/db/sql:/docker-entrypoint-initdb.d ports: - 3306:3306 phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin environment: - PMA_ARBITRARY=1 - PMA_HOST=db-host - PMA_USER=docker - PMA_PASSWORD=docker links: - db ports: - 8080:80 volumes: - /sessions各項目について簡単に説明します。
詳しくは公式リファレンスを見てみましょう。https://docs.docker.com/compose/compose-file/image
ローカルやリモートにあるイメージを指定します。ローカルにない場合リモートからpullされます。
今回はnginx、mysql、phpmyadminはローカルのイメージを指定しています。
build
イメージをbuildする際に参照するファイルを指定します。
要はイメージを構築する場合はこちらを使うわけです。またbuildとimageを両方指定することはできません。今回はphpコンテナの構築でDockerfileを使うため、そのディレクトリのパスを指定しています。
volumes
ボリュームとしてマウントするパスを指定します。
ホスト:コンテナ
またアクセスモードを読み取り専用する場合ホスト:コンテナ:ro
とします。今回はアクセスモードを指定しないため
rw
となり、書き込みもできるボリュームです。ports
公開(expose)するポートをします。
ホスト:コンテナ
とします。ポートが被る場合はここを変更します。
links
コンテナにリンクさせるサービス名を指定します。
注)コンテナ名(container_name
)ではなくサービス名今回はphpmyadminのコンテナにてdb-hostコンテナのサービス名である
db
を指定しています。phpのDockerfileの作成
phpコンテナではLaravelの実行のためにcomposerのインストールします。
公式(https://getcomposer.org/download/) から下の部分を#Composer install
のところに貼り付けます。DockerfileFROM php:7.2-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y zlib1g-dev mariadb-client \ && docker-php-ext-install zip pdo_mysql #Composer install RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" RUN php -r "if (hash_file('sha384', 'composer-setup.php') === 'c5b9b6d368201a9db6f74e2611495f369991b72d9c8cbd3ffbc63edff210eb73d46ffbfce88669ad33695ef77dc76976') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" RUN php composer-setup.php RUN php -r "unlink('composer-setup.php');" RUN mv composer.phar /usr/local/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www RUN composer global require "laravel/installer"PHP設定ファイルの作成
docker/php/にphp.iniを作成します。
php.ini[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"nginxの設定ファイルの作成
docker/nginxにdefault.confを作成します。
default.confserver { listen 80; index index.php index.html; root /var/www/public; location / { root /var/www/public; index index.html index.php; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }dockerの起動
下記コマンドでdockerを起動させます。初回は結構時間がかかります。
docker-composeではup
によってイメージの構築、コンテナの起動を行いますが、初回はキャッシュがないため--build
をつけます。-d
オプションによってバックグラウンドで起動させます。$ docker-compose up -d --buildlaravelプロジェクトの作成
まずはphpコンテナに入ります。コンテナに入る場合は
exec
コマンドを実行します。$ docker-compose exec php bashlaravelの新規プロジェクトを作成します。
composer create-project --prefer-dist "laravel/laravel myapplaravelプロジェクトの環境設定
laravelプロジェクト内の.envやconfig/detabase.phpのデータベースの設定を変更します。
DB名、ユーザ名、パスワードなどを先ほどdocker-compose.ymlに設定した値に変更しましょう。動作確認
nginx、php
http://localhost にアクセスしlaravelのホームページが表示されればOK。
mysql、phpmyadmin
phpコンテナに入り、migrateします。
$ docker-compose exec php bash $ php artisan migratehttp://localhost:8080 にアクセスし、phpmyadminが立ち上がりDB内に2つのテーブルが作成されていれば成功。
最後に
laradockも簡単にできますが、少しの知識があればこちらの方法のほうがシンプルで分かりやすいと思います。
laradockを使いたい方はこちら→https://qiita.com/rope19181/items/da31dc2cd6097315fa10
- 投稿日:2020-02-11T14:32:04+09:00
dockerでLaravel環境構築
はじめに
dockerによってLaravelの環境構築を行います。できるだけシンプルな構成を目指します。laradockは使いません。
自分は以前laradockを使っていましたが、
・プロジェクトが必要以上に大きくなる
・dockerの知識がほとんどなくても環境構築できでしまう
これらの点からlaradockを使わない方法を試していきます。laradockはとりあえずdockerでLaravelを立ち上げたい方、知識が全くない方は使うとよいかもしれません。
以前にlaradockによるlaravelの環境構築の記事を書きましたので、laradockを使いたい方はこちらを→https://qiita.com/rope19181/items/da31dc2cd6097315fa10
環境・仕様
・nginx上でPHP実行環境を構築し、Laravel新規プロジェクト作成。
・mysqlとwebGUIとしてphpmyadminも使えるようにします。・環境、仕様は以下の通りです。
Docker version 19.03.5
docker-compose version 1.24.1
php 7.2-fpm
mysql 5.7構成
最終的にこのような構成となります。
project
├ docker
│ ├ db
│ │ ├ data
│ │ ├ my.conf
│ │ └ sql
│ │
│ ├ nginx
│ │ └ default.conf
│ │
│ └ php
│ ├ Dockerfile
│ └ php.ini
├ myapp
└ docker-compose.yml今回はprojectをルートディレクトリとしています。
./myapp
はlaravelのプロジェクトを置くディレクトリとなります。docker-compose.ymlの作成
docker-composeでは複数のコンテナを管理、構築するためにdocker-compose.ymlに各コンテナの環境設定を定義します。
docker-compose.ymlversion: '3' services: php: container_name: php build: ./docker/php volumes: - ./myapp/:/var/www nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./myapp/:/var/www - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php db: image: mysql:5.7 container_name: db-host environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: database MYSQL_USER: docker MYSQL_PASSWORD: docker TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - ./docker/db/data:/var/lib/mysql - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/db/sql:/docker-entrypoint-initdb.d ports: - 3306:3306 phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin environment: - PMA_ARBITRARY=1 - PMA_HOST=db-host - PMA_USER=docker - PMA_PASSWORD=docker links: - db ports: - 8080:80 volumes: - /sessions各項目について簡単に説明します。
詳しくは公式リファレンスを見てみましょう。https://docs.docker.com/compose/compose-file/image
ローカルやリモートにあるイメージを指定します。ローカルにない場合リモートからpullされます。
今回はnginx、mysql、phpmyadminはリモートのイメージを指定しています。
build
イメージをbuildする際に参照するファイルを指定します。
要はイメージを構築する場合はこちらを使うわけです。またbuildとimageを両方指定することはできません。今回はphpコンテナの構築でDockerfileを使うため、そのディレクトリのパスを指定しています。
volumes
ボリュームとしてマウントするパスを指定します。
ホスト:コンテナ
またアクセスモードを読み取り専用する場合ホスト:コンテナ:ro
とします。今回はアクセスモードを指定しないため
rw
となり、書き込みもできるボリュームです。ports
公開(expose)するポートをします。
ホスト:コンテナ
とします。ポートが被る場合はここを変更します。
links
コンテナにリンクさせるサービス名を指定します。
注)コンテナ名(container_name
)ではなくサービス名今回はphpmyadminのコンテナにてdb-hostコンテナのサービス名である
db
を指定しています。phpのDockerfileの作成
phpコンテナではLaravelの実行のためにcomposerのインストールします。
公式(https://getcomposer.org/download/) から下の部分を#Composer install
のところに貼り付けます。DockerfileFROM php:7.2-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y zlib1g-dev mariadb-client \ && docker-php-ext-install zip pdo_mysql #Composer install RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" RUN php -r "if (hash_file('sha384', 'composer-setup.php') === 'c5b9b6d368201a9db6f74e2611495f369991b72d9c8cbd3ffbc63edff210eb73d46ffbfce88669ad33695ef77dc76976') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" RUN php composer-setup.php RUN php -r "unlink('composer-setup.php');" RUN mv composer.phar /usr/local/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www RUN composer global require "laravel/installer"PHP設定ファイルの作成
docker/php/にphp.iniを作成します。
php.ini[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"nginxの設定ファイルの作成
docker/nginxにdefault.confを作成します。
default.confserver { listen 80; index index.php index.html; root /var/www/public; location / { root /var/www/public; index index.html index.php; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }dockerの起動
下記コマンドでdockerを起動させます。初回は結構時間がかかります。
docker-composeではup
によってイメージの構築、コンテナの起動を行いますが、初回はキャッシュがないため--build
をつけます。-d
オプションによってバックグラウンドで起動させます。$ docker-compose up -d --buildlaravelプロジェクトの作成
まずはphpコンテナに入ります。コンテナに入る場合は
exec
コマンドを実行します。$ docker-compose exec php bashlaravelの新規プロジェクトを作成します。
composer create-project --prefer-dist "laravel/laravel myapplaravelプロジェクトの環境設定
laravelプロジェクト内の.envやconfig/detabase.phpのデータベースの設定を変更します。
DB名、ユーザ名、パスワードなどを先ほどdocker-compose.ymlに設定した値に変更しましょう。動作確認
nginx、php
http://localhost にアクセスしlaravelのホームページが表示されればOK。
mysql、phpmyadmin
phpコンテナに入り、migrateします。
$ docker-compose exec php bash $ php artisan migratehttp://localhost:8080 にアクセスし、phpmyadminが立ち上がりDB内に2つのテーブルが作成されていれば成功。
docker-composeコマンド小まとめ
よく使うものをまとめます。
up
コンテナの構築、起動をします。
似たものとしてイメージの構築のみを行う
build
、コンテナの起動のみを行うstart
などがありますが、docker-composeではとりあえずup
をしとけばいいと思います。
Dockerfileを更新した時などはbuild
しましょう。$ docker-compose up -d $ docker-compose up -d --build #初回の起動などbuildもしたいときdown
up
で作られたものを削除します。down
だけだとコンテナとネットワークの削除を行います。オプションによってその範囲を指定します。$ docker-compose down
コンテナ、イメージ、ボリュームそしてネットワークすべてを削除したい場合は
$ docker-compose down --rmi all --volumesexec
起動中のコンテナでコマンドを実行
$ docker-compose exec コンテナ名 実行するコマンド $ docker-compose exec コンテナ名 bash #コンテナに入る場合最後に
laradockも簡単にできますが、少しの知識があればこちらの方法のほうがシンプルで分かりやすいと思います。
laradockを使いたい方はこちら→https://qiita.com/rope19181/items/da31dc2cd6097315fa10
- 投稿日:2020-02-11T01:40:44+09:00
Knexあれこれ(雑多メモ)
はじめに(次の見出しまで飛ばしてOK)
最近仕事に対する楽しみ方を意識するようになり、今のつまらない仕事が続くのも嫌だったので、6月で辞めますと退職連絡を済ませてきた。
コーディングしてる最中はプライベートでも仕事でも楽しいので、コードをびっしり書くような会社に転職したいと思ったが、個人での活動実績はない。
とりあえず就活に繋がる作品を何か作ってみようと思い立ちこれ1本で大体何とか済ませちゃうNode.jsの勉強を1週間前に始めた。
が、DB処理があまり好きになれなかった。適当に買った参考書に書いてたDB処理は以下のようなもの
sql.jsconnection.query('SELECT * FROM hoge ', function (error, results, fields) { //取得結果に対する処理 });新卒配属された闇プロジェクトのシステム構成がこれに近い形式で実装されていたことが大体の原因ではあるが。
便利なnpmパッケージ Knex
PHP/Laravelあたりに言語/フレームワークを変更しようかなとこっそり考えつつ、何かいいnpmパッケージはないものかと探してみた。
あった(Knex公式)
記事を書いてくれている方もいた個人的に良いなと思った点
- チェーン形式で処理を書ける
- マイグレーションにも対応してる
軽く記事を流し読みるするだけでも結構便利に思えたのでリファレンス読みつつ色々試してみた。
で、ちょっと一々リファレンスを見に行くのもあれなのでちょっとメモを残そうと思いこの記事を書き始めた。正直公式リファレンスのは読みづらかった
割と参考記事とかぶってる点が多いので、多分knex回りを調べてこの記事を開いてくれた方は↑の参考記事を見ることをお勧めします。マイグレーションのあれこれメモ(本題)
実行前準備
初期構築 マイグレーションをするためのアレコレの準備
$ knex init
マイグレーション実行に当たる必要となる設定
module.exports = { // 開発環境の設定(デフォルトで参照される設定 NODE_ENVを書き換えればデフォルトではなくなる) development: { // データベースの種類 client: 'mysql', // DB接続設定 connection: { host : '127.0.0.1', user : 'root', password : '', database : 'node_app' }, // コネクションプールの設定 pool: { min: 2, max: 10 }, // マイグレーション設定 migrations: { // マイグレーションファイルの配置先(knexfile.jsからの相対) directory:'./db/migrations', // マイグレーションを管理するテーブル名 (マイグレーションの実行と同時にDBに作成される) tableName: 'knex_migrations' } }, // 開発環境とは異なる環境のマイグレーション実行設定定義 (本番環境,検証環境の差別化等) staging: { ... }, production: { ... }, };マイグレーションファイルの作成
<タイムスタンプ>_<ファイル名>.jsというファイルが、
migrations.directory
で設定したパス配下に配置される$ knex migrate:make <ファイル名>
マイグレーションファイルの中身の設定
細かく解説すると助長になるので、コメント参照
20200208161057_items.js// 後述する実行コマンドで呼び出されるメソッド exports.up = function(knex, Promise) { // connection.databaseで設定しているスキーマに引数で渡したテーブルがあるかチェック return knex.schema.hasTable('テーブル名') // hasTableのチェーンメソッド 判定結果を引数existsに渡して無名関数をコールバック .then(function(exists) { if (!exists) { // 接続先のスキーマに指定した名前でテーブルを作成する return knex.schema.createTable('テーブル名', // 作成したテーブルにカラムを作成する function(table) { // テーブルの要素設定 別途記載 table.increments('id').primary(); table.string('name', 100); table.integer('price'); }); }else{ return new Error("The table already exists. 2"); } }); }; // 後述する切り戻しコマンドで呼び出されるメソッド exports.down = function(knex, Promise) { return knex.schema.hasTable('items').then(function(exists) { if (exists) { // 指定したテーブルを削除する return knex.schema.dropTable('items'); } }); };接続先データベース/スキーマに対して実行するメソッド各種 (使いそうな奴だけ)
function(knex, Promise) { // テーブル作成メソッド コールバック内でカラム設定を忘れずに knex.schema.createTable(tableName, callback) // 指定したテーブル名を変更する knex.schema.renameTable(from, to) // 指定したテーブルを削除する knex.schema.dropTable(tableName) // 指定したテーブルが存在しないか確認する 上例のように.then()でチェーンするとスマート knex.schema.hasTable(tableName) // 指定したテーブルが存在すれば、そのテーブルを削除する. has,dropをチェーンしなくて済む knex.schema.dropTableIfExists(tableName) // 指定したテーブルに関する変更処理を実行する knex.schema.table(tableName, callback) };接続先のデータベース/スキーマが持つテーブルに対して実行するメソッド各種
createTableや、table関数のコールバック内で利用する
knex.schema.createTable('posts', function(table) { // 指定したカラムを削除する table.dropColumn(name) // 指定した複数のカラムを削除 table.dropColumns(*columns) // 指定したカラム名を変更 table.renameColumn(from, to) // オートインクリメント形式のカラムを追加 table.increments(name) // 文字列型のカラムを追加 オプション引数で長さも指定できる table.string(name, [length]) // 数値型のカラムを追加 table.integer(name) });主キーとか外部キーとかindexとかの使い方
カラム設定の関数にチェーンする
knex.schema.createTable('posts', function(table) { // 主キーの設定 table.increments(name).primary() // knexインスタンスがMySQLとPostgreSQLの場合のみ使える table.index(columns, [indexName], [indexType]) // 外部キーの設定 table.foreign(カラム名).references('参照テーブル.カラム名') table.string(name) table.foreign(name).references(table.name) });実行手順
未実行のマイグレーションファイルのupメソッドを、タイムスタンプの古い順に全ファイル実行
$ knex migrate:latest
envオプション: 実行対象の環境を指定してマイグレーションを実行する
$ knex migrate:latest --env production直前に実行した全てのマイグレーションファイルのdownメソッドを、タイムスタンプの新しい順に実行する
Latestでバッチ実行したなら、すべてのファイルをタイムスタンプの新しい順に実行する。
Upで個別実行したなら、そのマイグレーションファイルのみを実行する$ knex migrate:rollback
allオプション:過去に実行した全てのマイグレーションファイルのdownメソッドを実行する
$ knex migrate:rollback --allタイムスタンプが最も古い未実行のマイグレーションファイルのUpメソッドを実行する
$ knex migrate:up
マイグレーションファイルを指定してそのUpメソッドを実行する
$ knex migrate:up <ファイル名>.js
タイムスタンプが最も新しい実行済のマイグレーションファイルのdownメソッドを実行する
$ knex migrate:down
マイグレーションファイルを指定してそのdownメソッドを実行する
$ knex migrate:down <ファイル名>.js
マイグレーションファイルを一覧表示する
実行済みのものと未実行のものに分割してリスト表示してくれる
$ knex migrate:list Using environment: development Found 1 Completed Migration file/files. 20200208145923_items.js Found 1 Pending Migration file/files. 20200208161057_items.js
作成日の異なるマイグレーションファイルがある場合のmigrate:latestの挙動
タイムスタンプの古い方から実行される
/project |--migration | |--20200208161057_items.js | |--20200208161542_items.js20200208161057_items.jsexports.up = function(knex, Promise) { console.log('items oldest'); }20200208161542_items.jsexports.up = function(knex, Promise) { console.log('items lastest'); }実行結果$ knex migrate:latest Using environment: development items oldest items latest
作成日の異なるマイグレーションファイルがある場合のmigrate:rollbackの挙動
タイムスタンプの新しい方から実行される
/project |--migration | |--20200208161057_items.js | |--20200208161542_items.js20200208161057_items.jsexports.up = function(knex, Promise) { console.log('items oldest'); }20200208161542_items.jsexports.up = function(knex, Promise) { console.log('items lastest'); }実行結果$ knex migrate:rollback Using environment: development items latest items oldest
オプション引数類は一例で上げてるだけになります。詳細は公式へ
migrate:latestの後にもう1回migrate:latestをした場合のmigrate:rollbackの挙動
上述した通り、migrate:rollback は直前の1回の実行を戻す
2回に分けた場合は2回実行するか、--all
オプション を使うぼやき
結構前からあるパッケージなのにknexの日本語記事少ないってことは、
割とNode.jsを書いてる人からは不人気なのだろうか。
- 投稿日:2020-02-11T00:18:42+09:00
WindowsでグローバルIPアドレスを確認する方法
確認したい理由
Azure で
Azure Database for MySQL
を立てたのだが、接続するためにファイアウォール規制に許可サービスとして自IPアドレスを登録する必要があった。環境
Windows10 Home
XAMPP 7.3.11
Azure Database for MySQL 5.7ipconfig /all ではわからない
ipconfig /all
叩けばわかるだろうと思ったのだが、載っていなかった。Webサービスで調べる
以下のサイトで調べる。アクセスすれば載っている。
アクセス情報【使用中のIPアドレス確認】
https://www.cman.jp/network/support/go_access.cgi結果
無事にわかり接続できた
余談
ちなみにコマンドラインからMySQLで接続しようとしたら、、、
C:\xampp\mysql\bin>mysql --host mysql-hogehoge.mysql.database.azure.com --user hogehoge@mysql-hogehoge -p Enter password: ********あなたのグローバルIPは許可されてないよ!と出るのでこれでもわかる。
ERROR 9000 (HY000): Client with IP address 'xxx.xxx.xxx.xxx' is not allowed to connect to this MySQL server.