VIEW (представление) — это сохранённый в базе данных SELECT-запрос, у которого есть имя, и который можно использовать в других запросах как обычную таблицу. VIEW не хранит данные физически — при каждом обращении к нему база выполняет исходный запрос заново и возвращает актуальный результат. Это отличает VIEW от обычной таблицы: данные в представлении всегда свежие, потому что берутся напрямую из таблиц-источников в момент обращения.
Как создать и использовать VIEW на примере?
CREATE VIEW active_users AS
SELECT id, name, email
FROM users
WHERE is_active = true;
SELECT * FROM active_users WHERE name LIKE 'А%';
SELECT id, name, email
FROM users
WHERE is_active = true;
SELECT * FROM active_users WHERE name LIKE 'А%';
CREATE VIEW active_users AS ... сохраняет запрос под именем active_users. Дальше к этому имени можно обращаться как к обычной таблице — SELECT * FROM active_users выполнит исходный запрос (фильтр по is_active = true) и вернёт актуальные строки на момент обращения. Второй SELECT в примере добавляет к сохранённому в VIEW условию собственный фильтр по имени — VIEW можно использовать в более сложных запросах точно так же, как обычную таблицу.
Зачем нужен VIEW, если можно просто написать запрос?
VIEW решает три задачи одновременно: скрывает сложность часто повторяющегося запроса за простым именем (не нужно копировать один и тот же JOIN из пяти таблиц в десять разных мест кода), упрощает права доступа (можно дать пользователю доступ только к VIEW, скрывающему часть столбцов или строк исходной таблицы, не давая прямого доступа к самой таблице), и делает код более читаемым (SELECT * FROM active_users понятнее, чем повторение условия WHERE is_active = true в каждом запросе).
Когда через VIEW можно менять данные — INSERT/UPDATE/DELETE?
UPDATE active_users SET name = 'Новое имя' WHERE id = 42;
Некоторые VIEW позволяют выполнять INSERT/UPDATE/DELETE напрямую через них — изменения применяются к таблице-источнику. Это работает надёжно только для достаточно простых VIEW: без JOIN, без GROUP BY/агрегатных функций, без DISTINCT, обычно основанных на одной таблице. Как только VIEW усложняется агрегатами или DISTINCT, изменение данных через него становится невозможным напрямую в любой СУБД. С JOIN картина отличается по СУБД: в PostgreSQL UPDATE/INSERT через VIEW с JOIN запрещён полностью без исключений, а в MySQL точечное обновление столбцов, принадлежащих только ОДНОЙ из объединённых таблиц, может пройти — запрет срабатывает, только если правка одной командой пытается задеть столбцы сразу из нескольких таблиц. В обоих случаях правило одно: чем сложнее VIEW, тем менее надёжно через него можно писать данные — на практике для записи почти всегда используют таблицы-источники напрямую, а VIEW — только для чтения.
Когда нужен MATERIALIZED VIEW вместо обычного VIEW?
CREATE MATERIALIZED VIEW sales_summary AS
SELECT user_id, SUM(amount) AS total
FROM orders
GROUP BY user_id;
REFRESH MATERIALIZED VIEW sales_summary;
SELECT user_id, SUM(amount) AS total
FROM orders
GROUP BY user_id;
REFRESH MATERIALIZED VIEW sales_summary;
Обычный VIEW выполняет запрос заново при каждом обращении — для сложных запросов с тяжёлыми агрегациями это может быть медленно. MATERIALIZED VIEW (доступен в PostgreSQL и Oracle) физически сохраняет результат запроса на диске, как обычная таблица, и отдаёт его мгновенно при обращении — но данные в нём не обновляются автоматически при изменении таблиц-источников. Обновление происходит только по явной команде REFRESH MATERIALIZED VIEW. Это компромисс между скоростью чтения и свежестью данных: подходит для отчётов и дашбордов, где не критично видеть данные секунда-в-секунду, а важна скорость выдачи при частых обращениях.
Обычная таблица vs VIEW vs MATERIALIZED VIEW:
— Хранит данные физически. Таблица — да. VIEW — нет, только сохранённый текст запроса. MATERIALIZED VIEW — да, результат запроса сохранён на диске.
— Актуальность данных. Таблица — всегда (данные пишутся напрямую). VIEW — всегда, запрос выполняется заново при каждом обращении. MATERIALIZED VIEW — только на момент последнего REFRESH, может быть устаревшей.
— Скорость обращения. Таблица — высокая, прямое чтение. VIEW — зависит от сложности исходного запроса, который выполняется каждый раз заново. MATERIALIZED VIEW — высокая, как у обычной таблицы, результат уже посчитан.
— Когда подходит. Таблица — хранение первичных данных. VIEW — скрыть сложный запрос под простым именем, ограничить доступ, важна свежесть данных. MATERIALIZED VIEW — тяжёлые агрегации, где скорость выдачи важнее мгновенной свежести (отчёты, дашборды).
— Хранит данные физически. Таблица — да. VIEW — нет, только сохранённый текст запроса. MATERIALIZED VIEW — да, результат запроса сохранён на диске.
— Актуальность данных. Таблица — всегда (данные пишутся напрямую). VIEW — всегда, запрос выполняется заново при каждом обращении. MATERIALIZED VIEW — только на момент последнего REFRESH, может быть устаревшей.
— Скорость обращения. Таблица — высокая, прямое чтение. VIEW — зависит от сложности исходного запроса, который выполняется каждый раз заново. MATERIALIZED VIEW — высокая, как у обычной таблицы, результат уже посчитан.
— Когда подходит. Таблица — хранение первичных данных. VIEW — скрыть сложный запрос под простым именем, ограничить доступ, важна свежесть данных. MATERIALIZED VIEW — тяжёлые агрегации, где скорость выдачи важнее мгновенной свежести (отчёты, дашборды).
Частые вопросы про VIEW в SQL
VIEW физически хранит данные? Обычный VIEW — нет, это просто сохранённый текст запроса, который выполняется заново при каждом обращении. MATERIALIZED VIEW — да, хранит результат физически, но требует явного обновления (REFRESH), чтобы синхронизироваться с изменениями в исходных таблицах.
В чём разница между VIEW и обычной таблицей? Таблица физически хранит данные, которые в неё явно записали. VIEW — это именованный запрос: данные не хранятся в самом VIEW, а вычисляются из таблиц-источников каждый раз при обращении. Из-за этого VIEW всегда показывает актуальные данные, но может быть медленнее прямого обращения к таблице для сложных запросов.
Можно ли создать VIEW на основе другого VIEW? Да, VIEW можно строить на основе других VIEW — база при обращении просто развернёт всю цепочку вложенных запросов в один. Но глубокая вложенность VIEW друг в друга усложняет отладку и может замедлить выполнение, если оптимизатор не сможет эффективно объединить несколько уровней вложенности.
Зачем нужен VIEW для ограничения прав доступа? Если пользователю нужен доступ только к части столбцов таблицы (например, без столбца с зарплатой) или только к части строк (например, только к своим заказам), можно создать VIEW, который уже отфильтрован нужным образом, и выдать права на этот VIEW, а не на исходную таблицу. Пользователь физически не сможет обратиться к скрытым данным напрямую, потому что у него просто нет прав на таблицу-источник.
В чём разница между VIEW и обычной таблицей? Таблица физически хранит данные, которые в неё явно записали. VIEW — это именованный запрос: данные не хранятся в самом VIEW, а вычисляются из таблиц-источников каждый раз при обращении. Из-за этого VIEW всегда показывает актуальные данные, но может быть медленнее прямого обращения к таблице для сложных запросов.
Можно ли создать VIEW на основе другого VIEW? Да, VIEW можно строить на основе других VIEW — база при обращении просто развернёт всю цепочку вложенных запросов в один. Но глубокая вложенность VIEW друг в друга усложняет отладку и может замедлить выполнение, если оптимизатор не сможет эффективно объединить несколько уровней вложенности.
Зачем нужен VIEW для ограничения прав доступа? Если пользователю нужен доступ только к части столбцов таблицы (например, без столбца с зарплатой) или только к части строк (например, только к своим заказам), можно создать VIEW, который уже отфильтрован нужным образом, и выдать права на этот VIEW, а не на исходную таблицу. Пользователь физически не сможет обратиться к скрытым данным напрямую, потому что у него просто нет прав на таблицу-источник.
Закрепить VIEW и MATERIALIZED VIEW на практике
Понять, когда обычного VIEW достаточно, а когда нужен MATERIALIZED VIEW с явным REFRESH, проще всего на конкретных задачах с реальными данными, а не в теории. Потренироваться создавать VIEW поверх сложных запросов и разбираться с их обновляемостью в разных СУБД можно на тренажёре SQL Arena от Quality Academy — больше 800 задач, переключение диалекта, AI-ментор, значительная часть бесплатно.
-------
Полезные ссылки школы
Сайт Quality Academy:
https://quality-academy.ru/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena
https://quality-academy.ru/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena