Gymterview
middle

Что такое представления (views) и материализованные представления?

Представление (view) — именованный сохранённый запрос, выполняемый каждый раз при обращении. Материализованное представление (materialized view) — представление, результат которого физически сохраняется на диск. Выбор между ними — компромисс между актуальностью данных и скоростью чтения.

Обычное представление (VIEW)

Пример
CREATE VIEW active_clients AS
SELECT c.id, c.name, c.email, a.balance
FROM clients c
JOIN accounts a ON a.client_id = c.id
WHERE c.status = 'active' AND a.balance > 0;

-- Использование как обычной таблицы
SELECT * FROM active_clients WHERE balance > 100000;

Простые представления (одна таблица, без агрегаций) могут быть обновляемыми — допускают INSERT/UPDATE/DELETE.

Материализованное представление (MATERIALIZED VIEW)

Пример создания и использования
CREATE MATERIALIZED VIEW mv_monthly_stats AS
SELECT
    date_trunc('month', created_at) AS month,
    account_id,
    count(*) AS tx_count,
    sum(amount) AS total_amount,
    avg(amount) AS avg_amount
FROM transactions
GROUP BY date_trunc('month', created_at), account_id;

-- Создание индекса на материализованном представлении
CREATE UNIQUE INDEX idx_mv_stats ON mv_monthly_stats (month, account_id);

-- Запрос — быстро, читаем из предвычисленных данных
SELECT * FROM mv_monthly_stats WHERE account_id = 100;

-- Обновление данных (полная перестройка)
REFRESH MATERIALIZED VIEW mv_monthly_stats;

-- Обновление без блокировки чтения (требует UNIQUE INDEX)
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_monthly_stats;

Сравнение

Свойство VIEW MATERIALIZED VIEW
Хранение данных Нет (запрос каждый раз) Да (физически на диске)
Актуальность Всегда актуальные Данные на момент REFRESH
Скорость чтения Зависит от сложности запроса Быстро
Индексы Нет (используются индексы базовых таблиц) Можно создавать свои
INSERT/UPDATE/DELETE Возможно (для простых) Нет

Когда использовать materialized view

  • Тяжёлые аналитические запросы (отчёты, дашборды)
  • Данные обновляются редко или допустима небольшая задержка
  • Запрос читается часто, а базовые данные меняются нечасто

На собеседовании: REFRESH MATERIALIZED VIEW CONCURRENTLY — это ключевое слово, которое показывает знание production-практик: без CONCURRENTLY обновление блокирует чтение. Для CONCURRENTLY обязателен UNIQUE INDEX на materialized view.