Введение
Я начинаю использовать атрибуты добавления в моделях осенью 2019 года. В начале было просто запустить функцию, которая объединит два столбца, но теперь я использую их для некоторого анализа определенные модели, прежде чем отправить его на фронтэнд. Теперь я подозреваю, что это приведет к проблеме n + 1. Итак, давайте проверим некоторое использование атрибутов добавления.
Основы c использование
<?php
namespace App;
class User extends Authenticatable
{
protected $dates = ['deleted_at'];
protected $table = 'users';
protected $appends =
[
'full_name',
];
protected $fillable =
[
'username',
'first_name',
'last_name',
];
getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
}
}
Итак, что позволяет добавлять полное имя , мы знаем, что, но под капотом?
$user = User::find($id);
Использование дополнений с вышеупомянутой моделью извлечения практически не имеет значения для любого приложения. Если мы немного рассмотрим sh, что на самом деле происходит?
$users = User::get();
Теперь, запрос к базе данных такой же, как если бы мы ничего не добавляли? Другими словами, происходит ли добавление во время запроса к БД или после? Как бы то ни было, вам нужно полное имя, и если его нет в базе данных или на сервере, вы сделаете это во внешнем интерфейсе, так что это должно произойти в любом случае. Какой из трех является самым быстрым - это вопрос другого.
Немного более сложное использование
namespace App;
class User extends Authenticatable
{
protected $dates = ['deleted_at'];
protected $table = 'users';
protected $appends =
[
'full_name',
'last_post',
];
protected $fillable =
[
'username',
'first_name',
'last_name',
];
protected $hidden =
[
'password',
'remember_token',
];
public function posts()
{
return $this->hasMany('App\Post', 'user_id');
}
getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
}
getLastPostAttribute()
{
return $this->posts()->last()
}
}
Теперь очевидно, что если я сделаю $users->get();
, это будет привести к проблеме n + 1. Но если я сделаю это $users->with('posts')->get();
У меня проблема с n + 1 или худшая?
Если вы не используете проблему с n + 1
Проблема с n + 1 возникает, когда Вы создаете запрос, который должен будет сделать первоначальный вызов DB и один вызов для каждого объекта в массив. $users->get()
получит всех пользователей, а затем, поскольку я добавляю last_post, так как сообщение, где он не получен, будет выполнять вызов БД для каждой из моделей.
Что я хочу знать, это во втором случай $users->with('posts')->get()
, когда Laravel добавит last_post, узнает ли он, что в нем уже есть все сообщения? Так что нет необходимости загружать их во второй раз для каждого пользователя?