Eloquent ORM vs Query Builder (+ DB Facade )
Laravel で データ取得の方法と述べると、Eloquent ORM と Query Builder (+ DB Facade )の2つが上げられると思います。
今回は、二つのメリットとデメリットを見比べつつ、どういう状況で使えば良いのかを書きます。
Eloquent ORM
Eloquent ORMは、Laravel が提供している O/R マッパです。
ActiveRecord ライクにデータの取得ができます。
メリット
O/R マッパ のメリットを享受できる
- SQL という別の言語を、アプリケーション( Laravel )に介入せず済む
- テーブル同士の関係性を定義できる
- 再利用性や拡張性が高い
など...
今回は、O/R マッパについて述べるわけではないので、詳しくは書きません。
色々柔軟に設定できる
何ができるかは、ドキュメントを読めば一目瞭然です。
- 独自のグローバルスコープ適応による、独自メソッド実装
- 特定のイベントをフックにした処理の実行(いわゆるObserverパターン)
拡張性に優れた機能を、有していると言えます
デメリット
O/R マッパ のデメリットを享受する
- SQL が書けなくても、データ取得ができる
- ぱっと見、どういうクエリを発行しているのかわからない
- Eloquent O/R マッパは ActiveRecord パターンで実装されているので、ActiveRecord パターンを覚える必要がある
など...
こちらも、O/R マッパについて述べるわけではないので、詳しくは書きません。
ですが、「ぱっと見、どういうクエリを発行しているのかわからない」は、次のデメリットで関連して触れることになります。
特定のメソッドを使うと、サブクエリを使って実行する
例えば has や whereHas では、exists を使ったサブクエリを実行します。
参考: qiita.com
当然ながら、サブクエリを実行するわけなので、クエリの実行時間が長いことになります。中には join 句を使えばサブクエリにしなくて良いような内容も、サブクエリで実行します。
このデメリットは、O/R マッパのデメリットで挙げた「ぱっと見、どういうクエリを発行しているのかわからない」が躊躇に現れていると思います。
どういう時に使えば良いか
- パフォーマンスよりも安全性を取りたい
- 確実に、リレーションに沿ったデータ取得をしたい
- 特定の状況下での条件付けや、処理の実行を実装したい
Query Builder (+ DB Facade )
Laravel が提供しているクエリを生成するためのメソッド群。
SQL ライクにクエリを書くことができる( Query Builder )他、SQL をそのまま書いて実行する( DB Facade )こともできます。
メリット
Eloquent と比べて高速
join 句を使ったクエリを書けば、Eloquent でサブクエリを使って取得している処理よりも早くなります。
また、以下 URL では、同じ実行結果でも、Eloquent O/R マッパ に比べて Query Builder (+ DB Facade )の方が早いことを主張しています。
参考:https://www.youtube.com/watch?v=3TJfR1Ta4GU
どういうクエリを実行しているのかはわかりやすい
SQL 文と書き方に大きな差はないので、なんのクエリが発行されているかは非常にわかりやすいです。
SQL を書けさえすれば学習コストは低い
どんなメソッドがあるかは覚える必要があるものの、それ以外に必要なことは、SQL 文を書けることだけです。
デメリット
自力で考慮しなければいけない点がある
- テーブル同士の結合は自身で行う必要があるため、リレーションを正しく把握して反映する必要がある
- 論理削除の条件は、自分で条件指定する
- そもそも SQL 文で間違った書き方を書いてはいけない
など...
これらを正しく考慮できていないと、意図しないデータを取得してしまう場合があります。
また、個人開発ではなくチームによる開発であれば、レビュアーが上記の点を考慮してコードレビューしなければなりません。
どういう時に使えば良いか
- 複雑な条件や大量のデータを扱うので、パフォーマンスを求めたい(検索画面、一覧画面とか)
- 複雑な条件のクエリを、発行したい