Laravelで複数のデータベースに接続する方法

以前参画していた案件でAWSのRDSとRedshiftの2つのデータベースを利用して使い分けていたのでその際に調べたことをまとめようと思います。

## config/database.phpを修正
```php:database.php
'default' => env('DB_CONNECTION', 'mysql'),

'connections' => [

    省略...

    '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', ''),
        '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を使うこととしてデフォルトのままで1つ目の接続の設定としては特に修正は必要ありません。具体的な接続先の情報は.envファイルに記述してください！

2つ目の接続先を追加します。
```php:database.php
'connections' => [

    省略...

    // 追加
    'redshift' => [
        'driver' => 'pgsql',
        'host' => env('REDSHIFT_DATABASE_HOST', '127.0.0.1'),
        'port' => env('REDSHIFT_DB_PORT', '5439'),
        'database' => env('REDSHIFT_DB_DATABASE', 'forge'),
        'username' => env('REDSHIFT_DB_USERNAME', 'forge'),
        'password' => env('REDSHIFT_DB_PASSWORD', ''),
        'charset' => 'utf8',
        'prefix' => '',
        'search_path' => 'public',
        'sslmode' => 'prefer',
    ],

    省略...

]
```

これで準備は完了です。

## デフォルトのDBに接続する方法
デフォルトのDBに接続したい場合は何も気にする必要はありません。今まで通りに記述をすればデフォルトに接続されます！
もちろん以下のように明示的に記述しても接続する事ができます！
```php
DB::connection('mysql')->select('select * from users');

DB::connection('mysql')->table('users')
    ->where('name', $name)
    ->get();
```

## 2つ目のDBに接続する方法
```php
DB::connection('redshift')->select('select * from users');

DB::connection('redshift')->insert('insert into users(name) values(:name)', $name);
```

以下の書き方でも利用可能です。
```php
DB::connection('redshift')->table('users')
    ->where('name', $name)
    ->get();
```

## Modelを使用する方法
### デフォルトDBの場合
デフォルトの場合はクエリビルダと同じく特に何も気にする事なく使用する事ができます。
### 2つ目のDBにあるテーブルの場合
Modelファイルに接続情報を追記します

```php:Post.php
class Post extends Model
{ 
    /** @var string 2つ目のDB接続設定 */
    protected $connection = 'redshift';

    ...省略

}
```

ただ一つ注意点があります。
異なるDBのテーブル間でリレーションを設定する場合はデフォルトDBの方にも明示的に接続情報を追記してあげる必要があります。

```php:Comment.php
class Comment extends Model
{ 
    /** @var string デフォルトDB接続設定 */
    protected $connection = 'mysql';

    ...省略

}
```

## migrationファイルの設定方法
migrationファイルも前述と同じように何も指定しなければデフォルトのDBに接続します。
2つ目のDBに接続する書き方は以下です。
```php:1970_01_01_000000_create_users_table.php
class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::connection('redshift')->create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }
}
```

こちらの書き方でも大丈夫です。

```php:1970_01_01_000000_create_users_table.php
class CreateUsersTable extends Migration
{
    /** @var string 2つ目のDB接続設定 */
    protected $connection = 'redshift';

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }
}
```

2つのDBと接続する必要がある場合はこの書き方を試してみてください！

### 参考記事
https://chusotsu-program.com/laravel-multi-db/

https://tech.adseed.co.jp/20210310182908daN