SQL код скопирован в буфер обмена
EN PT FR

Урок 9.4: Представления (VIEW)

В предыдущем уроке мы говорили о временных таблицах, которые помогают сохранять промежуточные результаты на время сессии. Теперь рассмотрим другой важный инструмент SQL — представления. Они тоже помогают упростить работу со сложными запросами, но делают это иначе.

Представление позволяет сохранить SELECT-запрос под отдельным именем и затем использовать его повторно. Это особенно удобно в отчетах, аналитике и сценариях, где одну и ту же выборку нужно читать много раз.

SQL Views

Что такое представление

Представление (VIEW) — это объект базы данных, который хранит не сами данные, а SQL-запрос для их получения.

Проще говоря, представление можно воспринимать как «виртуальную таблицу»:

  • у него есть имя;
  • к нему можно обращаться через SELECT;
  • оно обычно показывает данные из одной или нескольких таблиц;
  • оно помогает скрыть сложную логику запроса за более простым интерфейсом.

Когда вы запрашиваете данные из представления, СУБД обычно выполняет сохраненный запрос и возвращает актуальный результат на основе исходных таблиц.

Базовый синтаксис

Представление создается с помощью CREATE VIEW:

CREATE VIEW view_name AS
SELECT column1, column2, column3
FROM table_name
WHERE condition;

После этого к представлению можно обращаться почти так же, как к таблице:

SELECT *
FROM view_name;

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

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

Допустим, мы хотим часто получать список клиентов с общей суммой их оплат. Вместо того чтобы каждый раз заново писать один и тот же запрос, можно создать представление:

CREATE VIEW customer_payment_summary AS
SELECT c.customer_id,
       c.first_name,
       c.last_name,
       SUM(p.amount) AS total_amount,
       COUNT(p.payment_id) AS payment_count
FROM customer c
JOIN payment p ON c.customer_id = p.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name;

Теперь использовать эту логику намного проще:

SELECT customer_id, first_name, last_name, total_amount
FROM customer_payment_summary
ORDER BY total_amount DESC;

SELECT AVG(total_amount) AS avg_customer_revenue
FROM customer_payment_summary;

Результат: сложная агрегация описана один раз внутри представления, а дальше с ней можно работать как с обычным набором данных в нескольких отдельных запросах.


Чем представление отличается от обычной таблицы

Хотя представление часто выглядит как таблица, между ними есть принципиальные различия.

1. Хранение данных

  • Обычная таблица хранит данные физически.
  • Представление обычно хранит только SQL-запрос.

2. Источник результата

  • Обычная таблица содержит собственные строки.
  • Представление показывает данные, полученные из других таблиц или даже из других представлений.

3. Актуальность данных

  • Обычная таблица изменяется только после INSERT, UPDATE или DELETE.
  • Представление обычно показывает текущее состояние исходных таблиц на момент выполнения запроса.

4. Назначение

  • Обычная таблица нужна для хранения бизнес-данных.
  • Представление нужно для упрощения чтения, повторного использования и логической организации запросов.

5. Изменение данных

  • Обычная таблица напрямую предназначена для вставки, обновления и удаления строк.
  • Представление в некоторых случаях тоже может поддерживать изменение данных, но это зависит от конкретной СУБД и от сложности запроса внутри VIEW.

Когда представления особенно полезны

Представления стоит использовать, если:

  • один и тот же запрос приходится многократно повторять;
  • нужно скрыть сложные JOIN, фильтры и агрегации за более простым именем;
  • важно дать пользователям или отчетам доступ не ко всей таблице, а только к нужным столбцам и строкам;
  • нужно сделать аналитический SQL более читаемым и поддерживаемым.

Например, можно создать представление только по дорогим фильмам:

CREATE VIEW expensive_films AS
SELECT film_id, title, rental_rate, rating
FROM film
WHERE rental_rate >= 4.00;

SELECT title, rental_rate
FROM expensive_films
ORDER BY rental_rate DESC, title;

Результат: основная логика фильтрации сохранена в одном месте, и в следующих запросах уже не нужно каждый раз повторять условие WHERE rental_rate >= 4.00.


Представление и временная таблица

Представления и временные таблицы могут решать похожие задачи, но между ними есть важные отличия.

  • Временная таблица обычно существует ограниченное время и хранит промежуточные данные отдельно.
  • Представление обычно является постоянным объектом схемы и хранит только запрос.
  • Временная таблица удобна, когда нужно физически сохранить промежуточный результат для нескольких шагов.
  • Представление удобно, когда нужно многократно переиспользовать одну и ту же логику выборки.
  • Временная таблица чаще используется внутри сценария обработки данных.
  • Представление чаще используется как удобный именованный слой доступа к данным.

Если вам нужен промежуточный результат, который должен существовать отдельно и, возможно, перерабатываться дальше, чаще подходит временная таблица. Если же нужно просто один раз определить удобное представление над существующими данными, обычно лучше использовать VIEW.


Можно ли изменять данные через представление

Во многих СУБД простые представления можно использовать не только для чтения, но и для изменения данных. Например, это возможно, если представление построено на одной таблице и не содержит сложных агрегатов, GROUP BY, DISTINCT или объединения нескольких таблиц.

Например, простое представление может выглядеть так:

CREATE VIEW active_customers_basic AS
SELECT customer_id, first_name, last_name, active
FROM customer
WHERE active = 1;

В некоторых СУБД через такое представление можно выполнять UPDATE. Но рассчитывать на это как на универсальное правило не стоит: чем сложнее логика представления, тем меньше вероятность, что оно будет обновляемым.

На практике представления чаще используют именно для чтения и упрощения запросов.


На что стоит обращать внимание

При работе с представлениями полезно помнить несколько правил:

  • давайте представлениям понятные имена, отражающие их смысл;
  • не прячьте в одно представление слишком много логики, если из-за этого оно становится трудно читаемым;
  • помните, что производительность запроса к представлению зависит от запроса внутри него и от исходных таблиц;
  • не предполагайте автоматически, что любое представление поддерживает INSERT, UPDATE или DELETE;
  • проверяйте, не проще ли в конкретной задаче использовать обычный SELECT, CTE или временную таблицу;
  • учитывайте особенности вашей СУБД, например наличие CREATE OR REPLACE VIEW или правила обновляемости.

Хорошо спроектированное представление делает SQL-код короче, понятнее и удобнее для повторного использования.


Пример из практики

Представим, что аналитикам регулярно нужен список фильмов с названием категории. Вместо того чтобы каждый раз писать одинаковые JOIN, можно создать представление:

CREATE VIEW film_category_details AS
SELECT f.film_id,
       f.title,
       f.rental_rate,
       c.name AS category_name
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
JOIN category c ON fc.category_id = c.category_id;

После этого любой запрос становится проще:

SELECT title, category_name, rental_rate
FROM film_category_details
WHERE category_name = 'Comedy'
ORDER BY rental_rate DESC, title;

SELECT category_name, COUNT(*) AS film_count
FROM film_category_details
GROUP BY category_name
ORDER BY film_count DESC;

Такой подход удобен тем, что сложная связка таблиц описана один раз. Дальше аналитики, отчеты и приложения могут использовать уже готовый логический слой без постоянного повторения одного и того же JOIN.


Ключевые выводы этого урока:

  • Представление (VIEW) хранит SQL-запрос, а не отдельную копию данных.
  • К представлению можно обращаться как к таблице, что упрощает повторное использование сложной логики.
  • Представления особенно полезны для отчетов, аналитики и сокрытия сложных JOIN и фильтров.
  • В отличие от временных таблиц, представления обычно являются постоянными объектами схемы и не предназначены для хранения промежуточных данных.
  • Не все представления поддерживают изменение данных, и это зависит от конкретной СУБД и структуры запроса.
  • Производительность представления зависит от того, насколько эффективно устроен запрос внутри него.

В следующем уроке мы рассмотрим материализованные представления и поймем, чем они отличаются от обычных представлений.