Laravel(6.x) 複数のデータベース(DB)に接続する

Laravelをインストールするとデフォルトでmysql接続設定が
記述されていますが、複数のデータベース(MySQL)に接続する場合
どのように対応すればいいのか紹介します
複数のデータベースにまたいで情報を取得する必要があるシステム、
他にはあるシステムから別システムにデータマイグレーションをする
といった場合に利用するかと思います

デフォルトコネクションを確認する

ここはおさらいなので、知っている人は飛ばしていただいてOKです!
デフォルトのmysql設定は以下のようになっていますが
これは ‘default’のところでコネクションを指定しなかった場合
どの接続子を使うか設定されています

'default' => env('DB_CONNECTION', 'mysql'),

'connections' => [

        'sqlite' => [
          // ... 割愛
        ],

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
...

.envの方を見てみると

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

となっているので
config/database.php
‘default’ => env(‘DB_CONNECTION’, ‘mysql’),

.env
DB_CONNECTION=mysql
がデフォルト接続の記述になります

ここではどちらも ‘mysql’ と書かれているので .envがあってもなくても
‘mysql’ の接続子が利用されます。

つまり ‘connections’配列の中の ‘mysql’ がデフォルトとして使われるわけですね

'connections' => [

        'sqlite' => [
          // ... 割愛
        ],

        'mysql' => [  // ←ここがデフォルトとして使われる

接続子を変更、追加する

では先程のデフォルト設定を踏まえて、mysqlデータベースを2つあった場合の
設定を行ってみたいと思います

Aシステムのデータベース : mysql_system_a
Bシステムのデータベース : mysql_system_b

とコネクションを識別する名称は上記とします

config/database.phpを修正

    'default' => env('DB_CONNECTION', 'mysql_system_a'),

    'connections' => [

        'sqlite' => [
         // ...割愛
        ],

        'mysql_system_a' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL_A'),
            'host' => env('DB_HOST_A', '127.0.0.1'),
            'port' => env('DB_PORT_A', '3306'),
            'database' => env('DB_DATABASE_A', 'forge'),
            'username' => env('DB_USERNAME_A', 'forge'),
            'password' => env('DB_PASSWORD_A', ''),
            'unix_socket' => env('DB_SOCKET_A', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

      'mysql_system_b' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL_B'),
            'host' => env('DB_HOST_B', '192.168.0.10'),
            'port' => env('DB_PORT_B', '3306'),
            'database' => env('DB_DATABASE_B', 'forge'),
            'username' => env('DB_USERNAME_B', 'forge'),
            'password' => env('DB_PASSWORD_B', ''),
            'unix_socket' => env('DB_SOCKET_B', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
  1. ‘default’のところを ‘mysql’から’mysql_system_a’に変更しました
    mysqlという識別子がなくなることや、常にコネクションを指定するのも
    面倒なので、基本となるデータベース側を設定しておくといいでしょう
  2. ‘connections’に元々あった’mysql’を’mysql_system_a’に変更しました
    envファイルから取得するキー名もすべて _Aをつけて区別できるようにしています
  3. ‘connections’にあらたに ‘mysql_system_b’を追加しました
    特にデータベースに違いがなければ 元々あったものをコピペで大丈夫です
    envファイルから取得するキー名はすべて _Bをつけています
    MySQLバージョンが古くcharsetがutf8mb4に対応出来ない場合(utf8の対応の場合)は
    ‘charset’ => ‘utf8’,
    ‘collation’ => ‘utf8_general_ci’
    とutf8の設定で対応するようになります

.envを修正

config/database.phpに正しい値を設定しておけば動作は問題ありませんが
開発環境、テスト環境、本番環境といった環境ごとに変更する必要がある
といったケースもあるので合わせて対応しておきましょう

DB_CONNECTION_A=mysql_system_a
DB_HOST_A=127.0.0.1
DB_PORT_A=3306
DB_DATABASE_A=laravel
DB_USERNAME_A=root
DB_PASSWORD_A=

DB_CONNECTION_B=mysql_system_b
DB_HOST_B=192.168.0.10
DB_PORT_B=3306
DB_DATABASE_B=laravel
DB_USERNAME_B=root
DB_PASSWORD_B=

それぞれ元々使われていたものは削除し、Aシステム用、Bシステム用に
2つ分用意しました

以上の設定で2つ分のデータベースの接続設定ができました

複数データベースの使い方

デフォルト設定のみを使っていた場合、使い分けをどうやるの?
がわからないと思うのであわせて載せておきます

デフォルト設定のみの場合のDBクエリ

$users = DB::select('select * from users');

複数DBで、コネクションを指定したDBクエリ

$users = DB::connection('mysql_system_b')->select('select * from users');

のように、DBファサードを使って指定するものにconnection()を使います
ちなみにクエリビルダの場合は

デフォルト設定のみの場合のDBクエリビルダ

$user = DB::table('users')->where('id', 1)->get();

複数DBで、コネクションを指定したDBクエリビルダ

$user = DB::connection('mysql_system_b')->table('users')->where('id', 1)->get();

クエリビルダの場合でもクエリと同じようにconnection()を指定すればOKです

以上、簡単にですがコネクションの使い分けの紹介でした

まとめ

マルチデータベースを扱うシーンはあまりないかもしれませんが
以前のデータベースも利用したい、古いシステムからマイグレーションしたい
といった場合にLaravelのコネクション設定を追加設定することで
簡単に実現できます