Представлення (view) - збережений SELECT з іменем, який можна читати як таблицю. Дані не зберігаються: при кожному зверненні MySQL виконує запит, що лежить в основі.
CREATE VIEW active_customers AS
SELECT u.id, u.email, COUNT(o.id) AS orders_count
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE u.deleted_at IS NULL
GROUP BY u.id, u.email;
SELECT * FROM active_customers WHERE orders_count > 5;
Як MySQL виконує представлення - два алгоритми:
MERGE |
TEMPTABLE |
|
|---|---|---|
| що робить | підставляє текст представлення в зовнішній запит | спершу виконує представлення в тимчасову таблицю, потім читає її |
| індекси базових таблиць | використовуються | для тимчасової таблиці - ні |
| можна оновлювати через представлення | так | ні |
| коли обирається | простий SELECT |
є GROUP BY, DISTINCT, агрегати, UNION, LIMIT, підзапит у списку колонок |
За замовчуванням (ALGORITHM = UNDEFINED) MySQL сам обирає MERGE, якщо це можливо. Представлення вище містить GROUP BY, тож воно завжди матеріалізується в тимчасову таблицю цілком - навіть якщо зовнішній запит просить один рядок. На великих таблицях це пастка продуктивності.
Оновлювані представлення: просте представлення з однієї таблиці дозволяє INSERT, UPDATE, DELETE. WITH CHECK OPTION забороняє записувати рядки, що не пройдуть умову WHERE представлення.
SQL SECURITY:
DEFINER(за замовчуванням) - запит виконується з правами того, хто створив представлення. Так можна дати користувачу доступ до частини колонок без прав на саму таблицю;INVOKER- з правами того, хто читає.
Якщо користувача-власника видалили, представлення з DEFINER перестає працювати з помилкою про неіснуючого definer - типова проблема після перенесення дампу на інший сервер.
Навіщо представлення: повторно використовувати складний запит, дати стабільний інтерфейс звітам і BI-інструментам, обмежити доступ до колонок.
У Laravel представлення створюють у міграції через DB::statement('CREATE VIEW ...'), а читають звичайною моделлю з protected $table = 'active_customers'. Перевіряйте план через EXPLAIN: рядок DERIVED означає, що представлення матеріалізувалося.