【Laravel】複数のデータベースを簡単に管理する方法を解説

Laravelは、優れた柔軟性と拡張性を持つPHPフレームワークです。その特徴の一つとして、複数のデータベースを同時に扱う機能があります。たとえば、ユーザー情報を管理するデータベースと、操作ログを保存するデータベースを分けて運用したい場合に、この機能が非常に役立ちます。

本記事では、Laravelで複数のデータベースを利用する際の設定方法や実践的な活用方法について解説します。以下のようなシナリオを想定して進めます。

  • 顧客情報とログデータをそれぞれ別々のデータベースに保存する方法
  • クエリビルダーやEloquentで特定のデータベースに接続する方法
  • マイグレーションを複数データベースで実行する際の注意点

Laravelを活用することで、プロジェクトの規模に応じた効率的なデータベース設計が可能になります。本記事を通じて、複数データベース構成を使いこなすための基礎を学びましょう!

複数データベースを扱う準備

Laravelで複数のデータベースを利用するには、まず適切な環境設定と接続情報の設定が必要です。このセクションでは、環境設定ファイルの更新と、設定ファイルへの接続情報追加の手順を解説します。

環境設定

複数のデータベースに接続するために、まず.env ファイルを編集します。それぞれのデータベース接続情報を記載しましょう。

以下は、デフォルトの接続情報(DB_CONNECTION)に加え、ログデータ用のデータベース接続情報を追加した例です。

# デフォルトのデータベース接続
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=main_database
DB_USERNAME=root
DB_PASSWORD=secret

# ログ用データベース接続
LOG_DB_CONNECTION=mysql
LOG_DB_HOST=127.0.0.1
LOG_DB_PORT=3306
LOG_DB_DATABASE=log_database
LOG_DB_USERNAME=root
LOG_DB_PASSWORD=secret

config/database.phpの編集

次に、config/database.php ファイルを編集し、新しい接続情報を追加します。Laravelはこの設定ファイルを通じて、データベース接続を管理します。

以下は、main_databaselog_database を設定する例です。

'connections' => [
    // デフォルトのデータベース接続
    'mysql' => [
        'driver' => 'mysql',
        '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' => '',
        'strict' => true,
        'engine' => null,
    ],

    // ログ用データベース接続
    'log_mysql' => [
        'driver' => 'mysql',
        'host' => env('LOG_DB_HOST', '127.0.0.1'),
        'port' => env('LOG_DB_PORT', '3306'),
        'database' => env('LOG_DB_DATABASE', 'forge'),
        'username' => env('LOG_DB_USERNAME', 'forge'),
        'password' => env('LOG_DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],
],

必要に応じて他のデータベースタイプ(PostgreSQL、SQLiteなど)も追加できます。

設定の確認

設定が完了したら、以下のコマンドでLaravelアプリケーションを再起動し、変更が適用されていることを確認します。

php artisan config:cache

これで、Laravelが複数のデータベース接続を正しく認識する準備が整いました。

クエリビルダーでの使い方

Laravelのクエリビルダーを使用すると、SQL文を直接書かずにデータベース操作を行うことができます。複数のデータベースを使用する場合、DB::connection() メソッドを用いて接続を切り替えることで、簡単に異なるデータベースを操作できます。

基本的な使い方

DB::connection('接続名') を使用して、特定のデータベース接続を選択できます。

以下は、デフォルトのデータベース(mysql)とログ用データベース(log_mysql)を切り替えてデータを取得する例です。

use Illuminate\Support\Facades\DB;

// デフォルトデータベースからデータを取得
$users = DB::connection('mysql')->table('users')->get();

// ログ用データベースからデータを取得
$logs = DB::connection('log_mysql')->table('logs')->get();
  • connection('接続名') で接続を明示することができます。
  • table('テーブル名') で、操作対象のテーブルを指定します。

データ挿入

複数のデータベースにそれぞれデータを挿入する例を見てみましょう。

// デフォルトデータベースにユーザーを追加
DB::connection('mysql')->table('users')->insert([
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'created_at' => now(),
    'updated_at' => now(),
]);

// ログデータベースにログを追加
DB::connection('log_mysql')->table('logs')->insert([
    'event' => 'User Created',
    'user_id' => 1,
    'created_at' => now(),
]);
  • insert() メソッドを使ってデータを挿入します。
  • 複数の接続で異なるテーブルに操作を行うことが可能です。

トランザクション

複数のデータベースでトランザクションを使用する場合、それぞれの接続で個別に管理する必要があります。以下は例です。

try {
    DB::connection('mysql')->beginTransaction();
    DB::connection('log_mysql')->beginTransaction();

    // デフォルトデータベースへの操作
    DB::connection('mysql')->table('users')->update(['status' => 'active']);

    // ログデータベースへの操作
    DB::connection('log_mysql')->table('logs')->insert([
        'event' => 'User Status Updated',
        'created_at' => now(),
    ]);

    // トランザクションのコミット
    DB::connection('mysql')->commit();
    DB::connection('log_mysql')->commit();

} catch (\Exception $e) {
    // ロールバック
    DB::connection('mysql')->rollBack();
    DB::connection('log_mysql')->rollBack();

    // エラー処理
    throw $e;
}
  • トランザクションは各接続ごとに分けて開始・終了する必要があります。
  • データベース間で整合性を保つために、例外処理を適切に実装することが重要です。

クエリビルダーを使うことで、データベース接続を明示的に指定しながら簡潔なコードで操作を実現できます。この方法は、シンプルなデータ操作を行う場面で特に便利です。

Eloquentでの使い方

Eloquentは、LaravelのORM(Object-Relational Mapping)機能で、データベース操作をモデルを通じて直感的に行える強力なツールです。複数のデータベースを操作する場合でも、モデルに適切な接続を指定するだけで簡単に利用できます。

モデルで接続を指定

複数のデータベースを扱う際、モデルの $connection プロパティで接続を指定します。

例として、users テーブルと log テーブルを、それぞれ異なるデータベースで管理する場合のモデルを作成します。

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $connection = 'mysql'; // デフォルトデータベース
    protected $table = 'users';      // テーブル名
}

class Log extends Model
{
    protected $connection = 'log_mysql'; // ログ用データベース
    protected $table = 'logs';           // テーブル名
}
  • $connection プロパティにデータベース接続名を設定します。
  • $table プロパティでテーブル名を指定できます。

データの操作

作成したモデルを使用して、異なるデータベースにデータを保存・取得する例を見てみましょう。

データの取得

// デフォルトデータベースからユーザーを取得
$users = User::all();

// ログ用データベースからログを取得
$logs = Log::where('event', 'User Created')->get();

データの保存

// 新しいユーザーを保存
$user = new User();
$user->name = 'Jane Doe';
$user->email = 'jane@example.com';
$user->save();

// 新しいログを保存
$log = new Log();
$log->event = 'User Registered';
$log->user_id = $user->id;
$log->save();

リレーションの設定

Eloquentではリレーションを利用できますが、異なるデータベース間のリレーションは直接サポートされていません。そのため、手動でリレーションを扱う必要があります。

users テーブルと log テーブル間のリレーションを扱う例を見てみましょう。

class User extends Model
{
    protected $connection = 'mysql';

    // ログを取得するカスタムメソッド
    public function logs()
    {
        return Log::where('user_id', $this->id)->get();
    }
}

class Log extends Model
{
    protected $connection = 'log_mysql';
}

使用例

$user = User::find(1); // ユーザーを取得
$logs = $user->logs(); // ユーザーのログを取得

トランザクション

Eloquentでトランザクションを扱う場合も、データベース接続ごとに管理が必要です。以下は、複数データベースでトランザクションを使用する例です。

use Illuminate\Support\Facades\DB;

try {
    DB::connection('mysql')->beginTransaction();
    DB::connection('log_mysql')->beginTransaction();

    // ユーザーの作成
    $user = User::create([
        'name' => 'John Doe',
        'email' => 'john@example.com',
    ]);

    // ログの作成
    $log = Log::create([
        'event' => 'User Created',
        'user_id' => $user->id,
    ]);

    // トランザクションをコミット
    DB::connection('mysql')->commit();
    DB::connection('log_mysql')->commit();

} catch (\Exception $e) {
    // エラー時にロールバック
    DB::connection('mysql')->rollBack();
    DB::connection('log_mysql')->rollBack();

    throw $e;
}
  • トランザクションは各データベースごとに管理します。
  • 例外処理を適切に実装し、整合性を確保します。

Eloquentは、複数のデータベース操作を簡潔に表現できる便利なツールです。ただし、データベース間のリレーションが直接サポートされていない点には注意が必要です。

マイグレーションの実行

Laravelで複数のデータベースを使用する場合、それぞれのデータベースに対応したマイグレーションを実行する必要があります。マイグレーションは、データベーススキーマを簡単に管理・更新するための強力な機能で、接続ごとにカスタマイズが可能です。

特定のデータベースでマイグレーションを実行する

Laravelでは、--database オプションを使用して、特定のデータベース接続を指定できます。以下は、log_mysql 接続に対してマイグレーションを実行する例です。

php artisan migrate --database=log_mysql

このコマンドを実行すると、log_mysql 接続に設定されたデータベースでマイグレーションが実行されます。

マイグレーションファイルの分離

複数のデータベースを管理する場合、それぞれのデータベースに対応したマイグレーションファイルを整理しておくと、プロジェクトの可読性と管理性が向上します。以下の手順を参考にしてください。

データベースごとのディレクトリを作成

database/migrations ディレクトリ内に、接続ごとのサブディレクトリを作成します。

mkdir -p database/migrations/main
mkdir -p database/migrations/log

マイグレーションファイルの配置

接続に応じてマイグレーションファイルを適切なサブディレクトリに移動します。下記にファイルの配置場所の例を挙げます。

  • database/migrations/main/2023_11_28_000000_create_users_table.php
  • database/migrations/log/2023_11_28_000001_create_logs_table.php

接続ごとにマイグレーションを実行

サブディレクトリに分けた場合でも、--pathオプションを使用して特定のディレクトリのみを対象にマイグレーションを実行できます。

php artisan migrate --database=mysql --path=database/migrations/main
php artisan migrate --database=log_mysql --path=database/migrations/log

このように、Laravelではマイグレーションも柔軟にカスタマイズできます。複数データベースを扱うプロジェクトでは、これらの方法を活用して効率的にスキーマを管理しましょう。

まとめ

Laravelで複数のデータベースを使用する方法について解説しました。この記事では、環境設定の基本からクエリビルダーやEloquentを用いた操作、さらにはマイグレーションの実行方法まで、幅広いトピックを扱いました。

Laravelの柔軟性を活かせば、複雑なマルチデータベース構成でも効率的に管理できます。本記事を参考に、自分のプロジェクトに適した構成を設計し、運用に活用してください。

コメント