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.