В этом туториале мы разберем пример как использовать MySQL представления (VIEW) в приложениях Laravel 8. Я приведу простой пример миграции создающей представление, объяснив шаг за шагом как использовать MySQL представления в Laravel.

Для примера создадим представление "view_user_data", в котором получим количество постов и комментариев пользователей без необходимости выполнять один и тот же запрос на сервер снова и снова.

SQL запросы на создание и удаление представления:

Создание представления

CREATE VIEW view_user_data AS
SELECT 
   users.id, 
   users.name, 
   users.email,
   (SELECT count(*) FROM posts
           WHERE posts.user_id = users.id
       ) AS total_posts,
   (SELECT count(*) FROM comments
           WHERE comments.user_id = users.id
       ) AS total_comments
FROM users

Удаление представления

DROP VIEW IF EXISTS `view_user_data`

Создание миграции:

Создадим файл миграции

php artisan make:migration create_user_view

Внесём в него изменения

<?php
  
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
class CreateUserView extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        \DB::statement($this->createView());
    }
   
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        \DB::statement($this->dropView());
    }
   
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    private function createView(): string
    {
        return <<<SQL
            CREATE VIEW view_user_data AS
                SELECT 
                    users.id, 
                    users.name, 
                    users.email,
                    (SELECT count(*) FROM posts
                                WHERE posts.user_id = users.id
                            ) AS total_posts
                FROM users
            SQL;
    }
   
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    private function dropView(): string
    {
        return <<<SQL

            DROP VIEW IF EXISTS `view_user_data`;
            SQL;
    }
}

Накатим миграцию

php artisan migrate

В результате получили представление следующего вида:

Работа с моделью и контроллером

Теперь создадим модель App/Models/ViewUserData.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ViewUserData extends Model
{
    use HasFactory;
    
    public $table = "view_user_data";
}

Эту модель будем использовать в контроллере App/Http/Controllers/UserController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\ViewUserData;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = ViewUserData::select("*")
                        ->get()
                        ->toArray();
          
        dd($users);
    }
  

При выполнении запроса к функции index получим следующий вывод:

array:12 [?

   0 => array:4 [?

       "id" => 1

       "name" => "Alayna Weimann"

       "email" => "audra.waelchi@example.org"

       "total_posts" => 2

   ]

   1 => array:4 [?

       "id" => 2

       "name" => "Herman Mann"

       "email" => "selena31@example.com"

       "total_posts" => 1

   ]

   2 => array:4 [?

       "id" => 3

       "name" => "Miss Greta Huels V"

       "email" => "kshlerin.alta@example.com"

       "total_posts" => 0

   ]

   3 => array:4 [?

       "id" => 4

       "name" => "Mr. Jaeden Kunze MD"

       "email" => "jast.derick@example.org"

       "total_posts" => 0

   ]

   4 => array:4 [?

       "id" => 5

       "name" => "Gerald Stoltenberg"

       "email" => "bashirian.earl@example.net"

       "total_posts" => 0

   ]

]

Таким образом мы создали представление MySQL и реализовали взаимодействие с ним. Надеюсь этот туториал был вам полезен!

Для справки

Представление или "виртуальная таблица" — объект базы данных, доступный для пользователя как таблица, но не содержащий данных. Актуальные данные представления извлекаются из привязанных к нему таблиц в момент обращения (в описанном выше примере представление "view_user_data" строится на основе таблиц "users" и "posts"). Представления нужны для упрощения работы с БД и ускорения времени ответа сервера, они часто используются для анализа данных, в том числе при построении витрин данных.