Laravel Eloquent — где в сводной таблице, потенциально очень большой запрос

Представьте себе сценарий в стиле Twitter, где один пользователь может следовать за другим. Затем пользователь может видеть сообщения (или твиты), которые сделали пользователи, за которыми он / она следит.

Пример структуры базы данных:

users (id, username, created_at, updated_at)
posts (id, user_id, body, created_at, updated_at)
follows (id, follower_id, followed_id, created_at, updated_at)

Модель пользователя

class User extends Eloquent implements UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

protected $table = 'users';

/* A user can follow another user */
public function followers()
{
return $this->belongsToMany('User', 'follows', 'follower_id', 'followed_id')->withTimestamps();
}

// ...
}

Теперь мой первоначальный подход с использованием Eloquent должен был сделать что-то вроде:

// Within the User model
public function getFeed()
{
// Ids of all follows
$ids = $this->follows()->lists('followed_id');

// Append this user's id
$ids[] = $this->attributes['id'];

// Grab up to 20 posts by people with these ids, ordered in descending order by date (Eager loading the user object associated with each post)
return Post::whereIn('user_id', $ids)->with('user')->latest()->take(20)->get();
}

Что приведет к следующим основным запросам:

select `followed_id` from `users` inner join `follows` on `users`.`id` = `follows`.`followed_id` where `follows`.`follower_id` = ?
select * from `posts` where `user_id` in (?, ?) order by `created_at` desc limit 20
select * from `users` where `users`.`id` in (?, ?)

В этом случае у меня в таблице только две записи пользователей, которые следуют друг за другом. Что бы произошло, если бы пользователь следил за 1 тысячей, 1 миллионом, 10 миллионами человек? Второй запрос станет очень длинным, возможно, слишком длинным? Возможно, такой подход вызовет другие проблемы.

Мой естественный подход к этой проблеме в SQL должен был бы сделать один запрос, что-то вроде:

SELECT p.body, p.created_at, u.username FROM follows AS f
LEFT JOIN posts AS p ON f.followed_id = p.user_id
LEFT JOIN users AS u ON p.user_id = u.id
WHERE f.follower_id = 1
ORDER BY p.created_at DESC
LIMIT 20

Подходит ли подход, который я выбрал, используя eloquent, и сможет ли он справиться (не зная количества записей пользователя / подписки, которые могут быть в будущем)? Если нет, есть ли другой подход, использующий eloquent, который был бы лучше? Было бы лучше сделать все в одном запросе SQL, как я сделал выше? Любые другие мысли / предложения приветствуются.

Мне нравится использовать Laravel с Eloquent, но я обеспокоен тем, что способ выполнения внутренних запросов может не всегда оказаться лучшим подходом. Это довольно умно, но я не ожидаю, что он сможет сделать все наилучшим образом.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]