この記事ではLaravelのEloquentでデータベースのレコード数をカウントする方法を紹介します。
Eloquentは、Laravelで簡単にデータベースにアクセスしてさまざまな操作ができるツールです。
簡単にレコード数を取得できる反面、パフォーマンスに関わる注意点もいくつかあるのでそれも含めて紹介していきます。
Eloquentでのカウントする方法
ここから実際にEloquentでカウントする方法を紹介しますう。
基本的なカウント方法
まずは基本的なカウントする方法。
Userモデルのレコード数を取得してみます。
$count = User::count();
// Userモデルのレコード数を取得
count()メソッドで対象のモデルクラスのカウント数を取得することができます。
最も基本的な使い方になります。
where句を使って条件に合致したカウント数を取得する
続いてwhere句である条件に合致するカウント数の取得方法を紹介します。
$activeUserCount = User::where('status', 'active')->count();
//ステータスが「active」なUserモデルのレコード数を取得
count()メソッドを使用する前にwhere句を使用します。
こうすることでwhere句で設定した条件に合致するレコード数を取得できます。
リレーション先のカウント数を一緒に取得するwithCount()メソッド
リレーション先のカウント数を同時に取得することもできます。
ユーザーが複数の投稿記事を持っている想定にします。
class User extends Model
{
public function posts()
{
return $this->hasMany('App\Models\Post');
}
}
UserとPostのリレーションが定義されていることが前提になります。
public function getIndex()
{
$usersWithPostCount = User::where('status', 'active')->withCount('posts')->get();
//紐づく投稿数も所持しているUserモデル
return view('user')
->with('usersWithPostCount', $usersWithPostCount);
}
withCount()メソッドでリレーション先のレコード数を一緒に取得することができます。
bladeなどで表示する際には以下のように書きます。
@foreach($usersWithPostCount as $user)
<p>ユーザー名: {{ $user->name }}, ポスト数: {{ $user->posts_count }}</p>
@endforeach
取得結果は、リレーションメソッドの名前に”_count”を追加したプロパティとしてアクセスできます。
count()メソッドを使用する際の注意点
これまでレコード数を取得する方法を紹介してきました。
ここからはcount()メソッドを使用する際の注意点を紹介します。
モデルのレコード数を取得する際の注意点
まず、User::get()->count()とUser::count()には違いがあります。
$count1 = User::count();
// 発行されるsql:select count(*) from users;
$count2 = User::get()->count();
// 発行されるsql:select * from users;
$count1では、まず全てのUser
モデルを取得します。
そのためデータベースから全てのレコードを取得しています。
一方$count2は、クエリでデータベースから直接カウントを行っています。
全レコードを取得するため$count1よりもDB負荷が高くなります。
大量のレコードを取得する場合には、User::count()を使用しましょう。
レコードの取得結果の違いについては以下記事も参考にしてみてください。
Laravelのデータ取得「find()」「first()」「get()」「all()」の違いを整理
リレーション先のレコード数を取得する際の注意点
次に、リレーション先のレコード数をカウントする際の注意点です。
$count3 = $user->posts()->count();
// 発行されるsql:select count(*) from posts where user_id = 1;
$count4 = $user->posts->count();
// 発行されるsql:select * from posts where user_id = 1;
2つの違いは「->posts()」か「->posts」かの違いです。
$count3は、リレーションメソッドで直接データベースからカウントを行います。
一方$count4は、リレーション先のposts
コレクションを取得してからカウントを行います。
全レコード取得してしまっているため$count3よりDB負荷が高くなります。
大量のレコードをカウントする場合やパフォーマンスを重視する場合には、User::count()や$user->posts()->count()のような直接データベースへのクエリを発行する方法が適しています。
効率的な方法でレコード数を取得できるようになろう
いかがだったでしょうか。
レコード数を取得する方法を紹介してきました。
レコード数を取得する際の注意点に関して、実際に発行されるSQL文を比較すると、違いが分かるかと思います。
ちょっとした違いで大きなパフォーマンスの差が出るのでレコード数を取得する際には注意しましょう。
エンジニアにおすすめ書籍
エンジニアになりたて、これから勉強を深めていきたいという方におすすめの書籍はこちら!