Сравнение Eloquent и построителя запросов с точки зрения
— производительности
— читабельности
— функциональности
— удобства использования
Laravel имеет встроенную ORM-библиотеку под названием Eloquent, упрощающую взаимодействие с базой данных. Eloquent ORM поддерживает шаблон Active Record, что означает, что каждая модель, которую вы создаете в своей структуре MVC, соответствует таблице в вашей базе данных. Здесь, модель PHPPost
будет соответствовать таблице постов. Вы можете получить доступ к данным таблицы постов следующим образом:
Post::all() // Получить все посты
Post::find($id) // Найти пост
Post::delete($id) // Удалить пост
В Eloquent ORM есть много подобных функций, упрощающих вашу работу. Eloquent также имеют функцию определения отношения между двумя или более таблицами.
Построитель запросов Fluent
Как следует из названия (fluent — гибкий, прим. пер.), он предоставляет гибкий интерфейс для создания и выполнения запросов базы данных. Построитель запросов Laravel повсюду использует PDO-привязку параметра, чтобы защитить ваше приложение от SQL-инъекций. Нет нужды очищать строки, передаваемые как привязки. Вот несколько примеров:
DB::table('posts')->get(); // Получить все посты
DB::table('posts')->where('id',$id)->first(); // Найти пост
DB::table('posts')->where('id',$id)->delete(); // Удалить пост
Laravel Eloquent или построитель запросов Fluent
И Eloquent и Fluent имеют свои плюсы и минусы. Сравним их по различным параметрам: читабельность кода, производительность и т.д.
Тест производительности
Я написал функцию для вставки 1000 строк в таблицу, используя Eloquent и Fluent, чтобы проверить их производительность.
Eloquent (время выполнения: 1.41 с, запросов выполнено: 1000)
Route::get("test",function(){
for($i=0;$i<1000;$i++){
$t=new Country();
$t->label=$i." Row";
$t->save();
}
});
Построитель запросов Fluent (время выполнения: 938 мс, запросов выполнено: 1000)
Route::get("test",function(){
for($i=0;$i<1000;$i++){
DB::table("countries")->insert(["label"=>$i." Row"]);
}
});
Нетрудно заметить, что Eloquent потребовалось немного больше времени на выполнение. Eloquent не использует какие-либо join-запросы, извлекая данные из двух таблиц. Поэтому, я думаю, можно сравнить производительность Eloquent и Fluent, получая доступ к данным из двух таблиц.
Eloquent – тип 1 (время выполнения: 2.72 с, запросов выполнено: 3000)
Route::get("test",function(){
for($i=0;$i<1000;$i++) {
$state = State::find(1)->with('Country')->first();
}
});
Eloquent – тип 2 (время выполнения: 2.16 с, запросов выполнено: 2000)
Route::get("test",function(){
for($i=0;$i<1000;$i++) {
$state = State::where('id',1)->with('Country')->first();
}
});
Fluent (время выполнения: 991 мс, запросов выполнено: 1000)
Route::get("test",function(){
for($i=0;$i<1000;$i++){
$state = DB::table('states')->where('states.id',1)
->join('countries','states.country_id','=','countries.id')
->select('countries.label as country','states.label as state')
->get();
}
});
Сравнив результаты тестов, можно сказать, что построитель запросов Fluent – явный победитель.
Читабельность кода
Мы легко можем судить о читабельности кода Eloquent и Fluent при помощи простого примера:
$post = Post::find($id); // вариант Eloquent
$post = DB::table('posts')->where('id',$id)->get(); // вариант Fluent
Просто прочитайте оба варианта. Какой проще? Очевидно, вариант Eloquent — более простой. С точки зрения читабельности кода Eloquent является явным победителем.
Функциональность
Eloquent является расширением Fluent. Вы можете использовать все функции Eloquent, которые могут использоваться в построителе запросов. Используя Eloquent, можно определить отношения между различными моделями, которые вы создали. Если вы хотите взять пост из базы данных вместе с тегами, категориями и комментариями, которые находятся в различных таблицах, то всё это можно получить, используя одну строчку кода:
Post::where('id',$id)->with('comments','tags','categories')->get();
Плюсы Eloquent
* Вы можете использовать все функции Fluent в Eloquent. Но вы не можете использовать функции Eloquent в построителе запросов
* Модель отношений Eloquent
* Простота в использовании
* Читабельность кода
Минусы Eloquent
* Время выполнения может незначительно увеличиться
* Иногда Eloquent проигрывает SQL-запросам, если запросы довольно сложные
Заключение
Eloquent и построитель запросов Fluent имеют свои достоинства и недостатки. Вы должны использовать их, опираясь на требования. Как и ко многим вещам, к ним применимо правило 80:20. Eloquent позаботится о 80% вашей работы, а остальные 20% — SQL и persistence код — вы сделаете с помощью Fluent. Не ждите слишком многого от Eloquent, иначе вы завершите проект с самыми странными ошибками и проблемами производительности.
Используйте Eloquent только в следующих ситуациях:
* Если вам нужны отношения между моделями
* Если вы хотите использовать Scope-методы
* Если вы хотите использовать некоторые вспомогательные функции в моделях
В противном случае используйте построитель запросов для повышения производительности.
Было бы неплохо услышать ваше мнение и мысли о Eloquent и проблемах, с которыми вы столкнулись при его использовании. Это одна из тех тем, где опыт использования особенно важен.