PHPからMySQLする方法について調べてみた

クラウドの部署に移動してきて、ゲーム業界を担当する様になってから、MySQLとPHPを知らないと、会話についていけない(;´д｀)ﾄﾎﾎ…
これまで MySQLもPHPも、少しは使った事あるけど、もっと深く理解する必要に迫られているので、調べてみた


# たくさん有りすぎてわからん
PHPからMySQLへ接続して、SQLを投げるだけと言って、いろんな方法があって、ネットを検索してサンプルコードの解説も読んでも、何を使ったら良いのやら、さっぱり良く判らん！？(◎＿◎;)  

迷っていたら、PHPのマニュアルページに記事を見つけた、その記事は「どの API を使うか 」(http://php.net/manual/ja/mysqlinfo.api.choosing.php )で、その解説によると、PDO か MySQLi だそうだ。

> mysqli か PDO_MySQL のどちらかを使うことをおすすめします。 古い mysql 拡張モジュールを新規開発で使うのはおすすめしません。 というのも、これは PHP 5.5.0 で非推奨となり、将来的に削除される予定だからです。


# PDO vs MySQLi

なんで、二つの種類があるわけよ（￣ー￣?）.....??ｱﾚ??　イッコ有れば良いじゃない、と思うけど、自由闊達なオープンソースの世界なので、そんな疑問は投げ捨てて検索!

PDOとMySQLiについて、判り易く比較した記事を発見した。書かれたのが2012と少し古いけど、判り易い。
http://code.tutsplus.com/tutorials/pdo-vs-mysqli-which-should-you-use--net-24059
この記事によれば、PDOを勧めしている。　確かに、他のデータベースも利用する事を考えると、良いかな。

それぞれ、以下のリンクにマニュアルがあるんだけど、機能の数でいうと、MySQLiが多くて便利そうだ。
 - PDOのマニュアル http://php.net/manual/ja/class.pdo.php
 - MySQLiのマニュアル http://php.net/manual/ja/book.mysqli.php

これだけでは、決めきれないなぁ。。。（ ﾟ ρ ﾟ )ﾎﾞｰｰｰｰ


# データベースとのコネクション・プーリング
PHPのサンプルコードを見ると、コードの先頭で、MySQLサーバーとコネクションをはっている。このステートメントを毎回書かないといけないのだろうか？。。。

長年Javaコンテナを使ったプロジェクトを担当していたので気になることがある。Javaのサーブレットコンテナには、コネクション・プーリングの機能があり、高負荷状態でも安定稼働できるためのもので、この機能は欲しい。

この疑問に対して、PHPのマニュアルの「持続的データベース接続」(http://php.net/manual/ja/features.persistent-connections.php) で、必要性について解説されていました。

しかし、PHPはJavaコンテナと違って、HTTPのGET等でアクセスされた時に、バッチ処理的に動作するので、データベースのコネクションを維持しておけるか疑問だけど、その辺の機構も含めて知りたいなぁ
((o(^-^)o))わくわく


## PDOの接続維持

接続維持の設定を入れる前と、入れた後の比較を実施してみます。 PHP5のプログラムとして、MySQLに接続してSELECT文を呼び出して終了するだけのプログラムを準備します。

まずは初期状態として、PHPの動作するウェブアプリサーバーの状態です。 PHP5とMySQLのセッションが一つも無いことがわかります。

```lang:netstatコマンド結果
vagrant@vagrant-ubuntu-trusty:~$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:44792           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 10.0.2.15:22            10.0.2.2:54293          ESTABLISHED
tcp        0      0 10.0.2.15:22            10.0.2.2:54292          ESTABLISHED
```

F5キーを連打すると、PHP5とMySQLのセッションを接続と切断を繰り返すので、TIME_WAITが大量に残るはずです。テストの結果は、以下のとおり、大量にTIME_WAITが表示されています。

```lang:netstatコマンド結果
vagrant@vagrant-ubuntu-trusty:~$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:44792           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 192.168.33.11:43904     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43905     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43917     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:80        192.168.33.1:54335      ESTABLISHED
tcp        0      0 192.168.33.11:43911     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43912     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43920     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43900     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43922     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43915     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43907     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43919     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43902     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43909     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 10.0.2.15:22            10.0.2.2:54293          ESTABLISHED
tcp        0      0 10.0.2.15:22            10.0.2.2:54292          ESTABLISHED
```

それでは、セッション維持の設定を有効にして、再テストします。 PDOでの設定は、phpファイルの接続のオプションとして設定するだけです。

```lang:test_pdo.php抜粋

 $dbh = new PDO($dsn,$user,$password,array(PDO::ATTR_PERSISTENT => true));
```

同じ様にF5キーを連打した後のnetstat の結果です。 以下の結果から、TIME_WAITが一個もなく、MySQLサーバーの3306ポートとセッションが維持されている事がわかります。

```lang:netstatコマンド結果
vagrant@vagrant-ubuntu-trusty:~$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:44792           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 192.168.33.11:43929     192.168.33.50:3306      ESTABLISHED
tcp        0      0 10.0.2.15:22            10.0.2.2:54293          ESTABLISHED
tcp        0      0 192.168.33.11:43928     192.168.33.50:3306      ESTABLISHED
tcp        0      0 10.0.2.15:22            10.0.2.2:54292          ESTABLISHED
tcp        0      0 192.168.33.11:80        192.168.33.1:54347      ESTABLISHED
```
PDOで、一度使用したセッションが再利用されている事が確認できました。 このセッションは、以下のコマンドを実行することで、無くなります。　最大同時数やクリーンナップ実施の時間などのパラメータは、見当たらないのですが、誰か知っているかたは、教えてください。　

```
root@vagrant-ubuntu-trusty:~# service php5-fpm restart
```


## MySQLiの接続維持

MySQLiで、データベース接続を維持する方法は、PHPのマニュアルの「mysqli 拡張モジュールでの持続的接続」(http://php.net/manual/ja/mysqli.persistconns.php )に書いてありました。　そのページの一番最後のとろこで、先頭にp:を付与するだけで良いそうです。

接続維持の設定を入れないで、テストすると、以下の様に毎回セッションを確立して解放するといった処理を実施した痕跡を示す TIME_WAIT が沢山出ています。

```lang:netstatコマンド結果
vagrant@vagrant-ubuntu-trusty:~$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:44792           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 192.168.33.11:43938     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 10.0.2.15:22            10.0.2.2:54293          ESTABLISHED
tcp        0      0 10.0.2.15:22            10.0.2.2:54292          ESTABLISHED
tcp        0      0 192.168.33.11:80        192.168.33.1:54589      ESTABLISHED
tcp        0      0 192.168.33.11:43941     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43942     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43940     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43939     192.168.33.50:3306      TIME_WAIT  
tcp        0      0 192.168.33.11:43937     192.168.33.50:3306      TIME_WAIT  
```

接続維持の設定はホストのIPアドレスの前に"p:"を付与するだけです。

```lang:test_mysqli.php
<?php
$mysqlhost = "p:192.168.33.50";
$username = "takara";
```

たったこれだけで、本当かなぁ。。。　と思うのですが、テスト結果は、以下の様にTIME_WAITがなく、セッションが維持されている事がわかりました。

```lang:netstatコマンド結果
vagrant@vagrant-ubuntu-trusty:~$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:44792           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 10.0.2.15:22            10.0.2.2:54293          ESTABLISHED
tcp        0      0 10.0.2.15:22            10.0.2.2:54292          ESTABLISHED
tcp        0      0 192.168.33.11:80        192.168.33.1:54600      ESTABLISHED
tcp        0      0 192.168.33.11:43944     192.168.33.50:3306      ESTABLISHED
tcp        0      0 192.168.33.11:43943     192.168.33.50:3306      ESTABLISHED
```

インフラ・エンジニアの立場としては、どちらを利用しても良さそうですね。

一応の確認が出来たのですが、もう一個 MySQL Native Driver　というものが出て来た
(ﾉﾟοﾟ)ﾉ ｵｵｵｵｫｫｫｫｫｫ-