Раздел 33 · PostgreSQL с нуля

Представления (VIEW)

junior~25 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

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

Окно в стене

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

Представление, по-английски view, устроено так же. Это запрос, который база хранит под именем. Обращаешься к нему как к таблице, а PostgreSQL каждый раз выполняет запрос заново на свежих данных. Своих данных у представления нет.

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

Выручка по книгам без отменённых заказов. Раньше мы писали этот запрос целиком, теперь сохраним:

CREATE VIEW book_sales AS
SELECT b.id, b.title,
       sum(oi.qty)            AS sold,
       sum(oi.qty * oi.price) AS revenue
FROM order_items oi
JOIN orders o ON o.id = oi.order_id
JOIN books b  ON b.id = oi.book_id
WHERE o.status <> 'cancelled'
GROUP BY b.id, b.title;

Дальше это обычное имя в FROM:

SELECT * FROM book_sales ORDER BY revenue DESC;
 id |       title        | sold | revenue
----+--------------------+------+---------
  8 | Совершенный код    |    1 | 2490.00
  1 | Мастер и Маргарита |    2 | 1380.00
  7 | Грокаем алгоритмы  |    1 | 1290.00
  3 | Пикник на обочине  |    2 |  900.00
  4 | Трудно быть богом  |    1 |  520.00
  5 | Шинель             |    1 |  250.00
(6 rows)

С представлением работают все приёмы прошлых уроков: WHERE, ORDER BY, JOIN с другими таблицами. Запрос «книги с выручкой больше тысячи» теперь умещается в строку:

SELECT title, revenue FROM book_sales WHERE revenue > 1000 ORDER BY revenue DESC;
       title        | revenue
--------------------+---------
 Совершенный код    | 2490.00
 Мастер и Маргарита | 1380.00
 Грокаем алгоритмы  | 1290.00
(3 rows)

Окно всегда свежее

Проверим, что представление ничего не хранит. Светлана наконец сделала первый заказ, «Собачье сердце»:

INSERT INTO orders VALUES (6, 4, '2026-10-09', 'new');
INSERT INTO order_items VALUES (6, 2, 1, 390.00);

SELECT * FROM book_sales WHERE id = 2;
 id |     title      | sold | revenue
----+----------------+------+---------
  2 | Собачье сердце |    1 |  390.00
(1 row)

Книга, которой только что не было в отчёте, появилась сама. Ничего обновлять не пришлось: представление выполнило свой запрос заново.

Зачем представления в жизни:

  • Не повторять сложный запрос. Логику «выручка без отменённых» описали один раз, и все отчёты берут её отсюда. Поменяется правило, поменяешь одно место.
  • Прятать лишнее. Аналитику можно дать доступ к представлению с городами покупателей, но без их имён, и не давать доступ к самой таблице. Как раздают такие права, разберём в уроке про роли.
  • Стабильное имя для приложения. Таблицы под представлением можно перестроить, а приложение продолжит читать то же имя с теми же колонками.

урок из курса

Урок из курса «PostgreSQL с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.