MySQLトリガーとLaravelオブザーバーの違い
目次[非表示]
- 1.はじめに
- 2.Laravelのオブザーバーとは何か?
- 2.0.1.使い方(登録方法)
- 3.MySQLのトリガーとは何か?
- 3.0.1.使い方(登録方法)
- 4.両者の比較
- 4.0.1.Laravelオブザーバー
- 4.0.2.MySQLトリガー
- 5.LaravelオブザーバーとMySQLトリガー、どちらを選択すべき?
- 6.まとめ
- 7.お悩みご相談ください
はじめに
データベースのテーブルにデータを追加した後に決められた処理を実施したい場合があると思います。
現在担当している案件では、LaravelとMySQLを使用しており、それぞれで上記のようなデータの操作に伴って決められた処理を実行できる仕組みがあることがわかりました。
そのためLaravelのオブザーバー機能とMySQLのトリガー機能について、それぞれの概要や実装方法、メリット・デメリットを調査しました。
Laravelのオブザーバーとは何か?
Laravelのオブザーバーは、Eloquentモデルにおける操作イベント(作成、更新、削除など)をキャッチして、関連するビジネスロジックを自動的に実行するクラスです。
オブザーバーはアプリケーションレベルで動作するので、Laravelの他の機能や依存関係の注入が簡単に行えます。
使い方(登録方法)
バージョン情報は以下のとおりです。
オブザーバーを使う場合は、モデルごとにオブザーバーを用意し、サービスプロバイダに登録する必要があります。
以下のコマンドを実行することでApp/ObserversディレクトリにUserObserver.phpというファイルが作成されます。
(例としてUserモデルを使用することを想定します)
作成されたファイルを確認すると以下のようになっています。
--model=User で指定したモデル名をもとに、Modelsディレクトリから参照していたりメソッドの引数に設定されていることがわかります。
オブザーバー内で使用できるメソッドはLaravelのイベント処理でフックしている処理を指定することができます。
https://readouble.com/laravel/11.x/ja/eloquent.html#events
例えばUserテーブルへ挿入される前に処理を行いたい場合は以下のメソッドを用意することで実現できます。
上記で用意したオブザーバーをモデルに関連づけるため、対応するモデルにObservedByアトリビュートを指定します。こうすることでEloquentイベントのオブザーバー機能を利用できます。
上記の設定はLaravelのバージョンが11のものになります。バージョンによって設定方法が異なりますので適宜公式ドキュメントを参考に設定しましょう。
https://laravel.com/docs/11.x/eloquent#observers
以上の設定を行うことで、例えば以下のような処理を行うとユーザーデータが作成された後にオブザーバーが動作しログが出力されるようになります。
MySQLのトリガーとは何か?
MySQLのトリガーは、テーブルに対する操作が行われるときに自動的に実行されるストアドオブジェクトです。
トリガーはデータベースレベルで動作するためアプリケーションに依存せず、データの整合性を高いパフォーマンスで維持することができます。
使い方(登録方法)
バージョン情報は以下のとおりです。
MySQLトリガーは、データベースに対して以下のようなSQL文を実行することで登録することができます。
例えば以下の処理では、Userテーブルにユーザーを追加したときに、作成したユーザーIDをUserHistoryテーブルに挿入するといった単純な履歴機能を提供することができます。
MySQLクライアントによってはDELIMITERが不要になる場合がありますが、一般的にはストアドプロシージャやトリガーを作成する際にはDELIMITERを使用することが推奨されます。ご利用の環境によって適宜設定を行なってください。
なお、作成したトリガーは以下のコマンドで確認することができます。
以上の設定を行うことで、アプリケーション側の処理によらず、データベースが行う操作をトリガーに処理が実行されるようになります。
両者の比較
LaravelオブザーバーとMySQLトリガーは、それぞれ異なる視点とレイヤーで動作するため、どちらが適しているかは具体的な要件や環境に依存します。以下では、両者の具体的な違いや特徴を比較します。
Laravelオブザーバー
- メリット
- コードベースで管理しやすい
- オブザーバーはオブザーバーの設定も含めアプリケーションのコードに含まれるため、コード管理システムでバージョン管理をすることができます。適切にコードを管理することによりMySQLトリガーと比べて案件の引き継ぎ漏れや設定のし忘れが発生しにくいです。
- コードの再利用性
- オブザーバーで定義された処理は再利用できます。複数のモデルで同じイベントに対する共通の処理が必要な場合は共通のオブザーバーを定義することでそれを再利用できます。
- コードベースで管理しやすい
- デメリット
- パフォーマンスの影響
- オブザーバーはアプリケーションレベルで動作するため、イベントが多く発生する場合や、オブザーバー内の処理が重い場合にはパフォーマンスに影響を与える可能性があります。
- すべての処理に使えるわけではない
- Eloquentのバルク操作(updateメソッドなど)では、saving、saved、updating、updatedイベントが発火しないため、特定のシチュエーションではイベントがトリガーされず、注意が必要です。(https://laravel.com/docs/11.x/eloquent#mass-updates)
- パフォーマンスの影響
MySQLトリガー
- メリット
- データの一貫性
- トリガーはデータベースレベルで動作するため、アプリケーション層を介さずにデータの整合性を保証します。これにより、異なるアプリケーションからのデータ操作でも一貫性を保つことができます。
- 自動化の容易さ
- トリガーを使用することで、特定の操作に対するアクション(例:ログの記録、関連テーブルの更新など)を自動化でき、手動での更新やエラーが発生しやすい処理を減少させることができます。
- データの一貫性
- デメリット
- デバッグが難しい
- トリガーはデータベース内で動作するため、データベースの処理でエラーが発生した際のデバッグが難しいです。SQLベースでのトリガーの管理や解析が必要となります。
- 移行時の管理が煩雑
- トリガーはデータベース内の定義になるため、データベースの移行の際や検証環境など新たに環境を準備する際にトリガーを設定する必要があり管理が煩雑になってしまいます。トリガーを設定するSQLスクリプトを適切に管理することが重要になります。
- デバッグが難しい
LaravelオブザーバーとMySQLトリガー、どちらを選択すべき?
個人的にはオブザーバーを選択します。
理由としては、何かしらのロジックなのであればすべてアプリケーションで処理を管理したいからです。バージョン管理ツールでコードを管理することもできますし、デバッグ機能のブレイクポイントの使用もできるため保守管理が楽になるからです。
一方トリガーは環境ごとにトリガーを設定する必要があるため、設定のし忘れが発生するリスクがあります。
まとめ
LaravelオブザーバーとMySQLトリガーの特徴を比較しました。
それぞれに独自のメリットと制約があり、どちらを選ぶかは、アプリケーションの要件や開発体制、運用環境に応じて適切な選択をすることが重要だと思います。
両者の特徴の理解および開発の一助となれば幸いです。