Pull to refresh

Как использовать MySQL представления (VIEW) в Laravel 8?

Original author: NiceSnippets

В этом туториале мы разберем пример как использовать 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"). Представления нужны для упрощения работы с БД и ускорения времени ответа сервера, они часто используются для анализа данных, в том числе при построении витрин данных.

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.