EloquentとQuery Builderのどちらを使うか
どちらもDBからデータを取得するために使用します。
*EloquentとQueryBuilderの説明は長くなるのでここでは省きます
*他にRawSQL(SQLの直書き)でデータベースを取得する方法もありますが、この記事では、よく使用されるEloquentとQueryBuilderに焦点をあてます。
Eloquent vs QueryBuilder。
どちらを、どのような場面で、いつ使うべきなのでしょうか?どう使い分けるのでしょうか?
結論、ケースバイケースで使い分けるべきと考えます。
シンプルなCRUD処理はEloquent、複雑なクエリはQueryBuilderと使い分けることが基本であると言われます。
一概に言えないですしチームの方針や、設計にも左右されると思います。適材適所で両方使っているプロジェクトも多いのではないでしょうか。
まず下記、EloquentとQueryBuilderのサンプルコードでは同じ結果が得られます。
class BookController extends Controller {
//Eloquent
$books = Book::with('author')->get();
//Query Builder (DB facade)
$books = DB::table('books')
->join('author', 'author.id', '=' , 'book.author_id')
->get();
}
パフォーマンスの観点だと、(たいていの場合)ORMよりQuery Builderの方がレスポンスは早いと言われれています。 RawSQL(SQLの直書き)であればさらに早いです 。
Eloquentは使わずにQuery Builderを使った方が良いのではないでしょうか?
上述に戻りますが、それではなぜEloquentも使用されているのでしょうか?
下記にEloquentとQuery Builderのメリット、デメリット、最後に考え得るユースケースをまとめます。
Eloquentのメリット、デメリット
メリット
・簡単、扱いやすく、シンプルに書けてビジネスロジックに専念できる。またDBの知識が浅くとも書ける
・コードの可読性が高く、メンテナンスしやすい
・テーブル名が変更となった際、Eloquent modelを1行変更すれば良いので対応が楽
例)
class Book extends model {
//テーブル名を「books」から「my_books」に変更。
protected $table = 'my_books';
}
・scopeを用いてSQLのロジックを使い回せる
例)
//fetch all published book
Book::where('status', 'published')->get();
//scopeでロジックを分離
public function scopePublished($query)
{
return $query->where('status', 'published');
}
//scopeを使用
Book::published()->get();
デメリット
・QueryBuilderに比べパフォーマンスが落ちる
・複雑なクエリを書く場合(複数のjoin, sort等)対応が難しい
・データベースの知識が浅いままになってしまう。
QueryBuilder(DB facade)のメリット、デメリット
メリット
・複雑なJOINや大量のデータを扱う際は、Eloquentよりパフォーマンスが上がる
・コードをチェーンで繋げて書けるためRawSQLより書きやすい
・SQLに書き慣れている人は比較的スラスラ書ける
デメリット
・コードの可読性が下がる
・RawSQLにはレスポンスが劣る
まとめ
個人的な意見も含まれますが、以上のメリット、デメリットを鑑みシンプルにまとめると下記のようなユースケースに別れるのではないでしょうか。
1)、シンプルなクエリやCRUD、浅いリレーションを扱うのであればEloquentを使う
2)、大量なデータや複雑なクエリ、リレーション、Eloquentがサポートしていないクエリを扱うのであれば、QueryBuilder(DB facade)を使う
上記したサンプルコードのようなシンプルなクエリであればEloquentを使うのが一般的かと思います。
また一つのプロジェクトの中でEloquentを使う箇所もあれば、QueryBuilde(DB facade)を使う箇所もあったりするのが一般的ではないでしょうか?
大事なのは適材適所でより良い方法を選択できるスキルです。(私はまだまだです←)
またORMに慣れてすぎてしまうとデータベースの内部構造を知らないままで開発ができてしまいます。
特に初学者にとってこれは成長の妨げになってしまうので、そういった観点からも両方(さらにはRaw SQLも)しっかり扱えるのが望ましいと考えます。
私もLaravelでの開発が長くなってくると、ちょいちょい生のSQLの書き方忘れてしまいます、、、(特にサブクエリやUNIONなど)
最後に。間違いや、他の考え等あればコメントいただけますと幸甚です。
参考
Comparison of performance between Raw
SQL and Eloquent ORM in Laravel
Laravel Eloquent Builder Vs Scopes
Laravel Eloquent vs query builder - Why use eloquent to decrease performance [closed]