SQL

БЛОК 11. Объекты БД — 26. VIEW (представления)

📚 24 вопросовПройти тест →
Лекция

БЛОК 11. Объекты БД — 26. VIEW (представления)

SQL

26. VIEW (представления)

🧭 Введение: зачем нужны представления

Когда в проекте растёт количество таблиц и JOIN-запросов, один и тот же SQL начинает дублироваться в разных местах.
VIEW помогает вынести сложную выборку в единый именованный слой и обращаться к нему как к «виртуальной таблице».
В этой теме разбираем базу:
  • что такое VIEW;
  • зачем он нужен в реальных задачах;
  • чем VIEW отличается от таблицы;
  • простой рабочий пример;
  • что такое materialized view (обзорно).
💡 Совет: Думайте о VIEW как о способе стандартизировать чтение данных, а не как о замене нормальной схемы.
Вывод: VIEW — это инструмент упрощения чтения и повторного использования SQL, особенно в отчётах и API-слое.

⚠️ Проблема -> решение

Типичная проблема:
  1. одна и та же бизнес-выборка копируется в десятках запросов;
  2. логика фильтров и JOIN со временем расходится между сервисами;
  3. любые изменения в схеме требуют массовых правок SQL.
Решение:
  1. вынести стабильные чтения в VIEW;
  2. дать команде единый интерфейс доступа к данным;
  3. использовать материализованный слой (materialized view) только там, где это реально нужно по производительности.
🟢 Если совсем просто: VIEW убирает дубли SQL и снижает риск «у каждого сервиса своя версия отчёта».
🎯 Как понять, что этап прошёл успешно: Один и тот же бизнес-отчёт читается из одного VIEW, а не собирается заново в каждом модуле.

🛠️ Чем помогает и как работает

VIEW не хранит данные как отдельная таблица (в обычном виде), а хранит определение запроса.
Когда вы делаете SELECT из VIEW, СУБД выполняет SQL, который лежит внутри него.
🟢 Если совсем просто: VIEW — это именованный SELECT, к которому можно обращаться как к таблице.
🎯 Как понять, что этап прошёл успешно: Вы умеете заменить повторяющийся JOIN-блок на VIEW без изменения бизнес-смысла.
Чем помогает:
  • уменьшает дублирование SQL;
  • упрощает чтение сложных запросов;
  • помогает скрыть лишние поля от потребителей;
  • ускоряет onboarding в проекте.
Как это работает:
  • Шаг 1: выделяем часто повторяющийся запрос;
  • Шаг 2: создаём CREATE VIEW ... AS SELECT ...;
  • Шаг 3: используем SELECT ... FROM view_name;
  • Шаг 4: при изменениях обновляем определение VIEW.
Вывод: VIEW — это слой абстракции для чтения, который делает SQL-логику централизованной.

📚 Ключевые термины (простыми словами)

Перед практикой синхронизируем словарь.
🟢 Если совсем просто: Важно различать «виртуальную выборку» (VIEW) и «физически сохранённые данные» (таблица).
🎯 Как понять, что этап прошёл успешно: Вы не путаете VIEW, таблицу и materialized view в проектных обсуждениях.
  • VIEW (представление) — сохранённый SQL-запрос, который выглядит как таблица при чтении.
  • Virtual table — «виртуальная таблица», у которой нет собственного набора строк как у обычной таблицы.
  • Materialized view — представление, результат которого физически сохраняется и обновляется отдельно.
  • Refresh — обновление данных materialized view.
  • Read model — слой чтения данных, адаптированный под отчёты и API.
Вывод: Термины помогают выбрать правильный инструмент под задачу чтения.

🧩 1. Что такое VIEW

VIEW — это объект БД, который хранит текст запроса и даёт к нему имя.
Для разработчика это способ работать с готовой бизнес-выборкой, не собирая её заново в каждом месте.
🟢 Если совсем просто: VIEW = заранее подготовленный SELECT, доступный как таблица.
🎯 Как понять, что этап прошёл успешно: Вы создаёте VIEW и читаете его обычным SELECT.
Назначение: Централизовать повторяющиеся запросы чтения.
Простыми словами: Один раз написали сложный SQL, дальше переиспользуете его по имени.
Для новичка: Обычный VIEW не хранит «свои» строки отдельно, он вычисляется на чтении.
Аналогия: Это как сохранённый фильтр в BI-системе: на входе те же данные, но способ показа уже зафиксирован.
Пример:
CREATE VIEW active_users_view ASSELECT  u.id,  u.email,  u.created_atFROM users uWHERE u.is_active = true;
SELECT  a.id,  a.emailFROM active_users_view a;
🔎 Как это происходит на практике:
  • Контекст: в API и админке нужен одинаковый список активных пользователей.
  • Действия: создают один VIEW и используют его в разных сервисах.
  • Результат: нет дублирования фильтра is_active = true в пяти местах.
Характеристики:
  • удобен для повторяющихся чтений;
  • упрощает SQL в прикладном коде;
  • не заменяет исходные таблицы.
Когда использовать: Когда одна и та же выборка повторяется в нескольких местах.
Вывод: VIEW — простой и надёжный способ сделать единый «контракт чтения».

🧪 2. Зачем используются VIEW

Главная ценность VIEW — не «магия производительности», а управляемость логики чтения.
Он помогает держать бизнес-правила фильтрации в одном месте.
🟢 Если совсем просто: VIEW нужен, чтобы не копировать один и тот же сложный SQL.
🎯 Как понять, что этап прошёл успешно: После изменения правила фильтра правится один VIEW, а не десятки запросов.
Назначение: Сделать слой чтения единообразным и поддерживаемым.
Простыми словами: Потребители получают «готовую витрину» данных.
Для новичка: VIEW часто используют как read-API внутри базы для отчётов и внутренних сервисов.
Аналогия: Это как публичный метод в классе: внутри сложность скрыта, снаружи понятный интерфейс.
Пример:
CREATE VIEW paid_orders_view ASSELECT  o.id,  o.user_id,  o.total_amount,  o.created_atFROM orders oWHERE o.status = 'paid';
SELECT  p.user_id,  COUNT(*) AS paid_ordersFROM paid_orders_view pGROUP BY p.user_id;
🔎 Как это происходит на практике:
  • Контекст: разные команды считают «оплаченные заказы» по-разному.
  • Действия: вводят единый paid_orders_view.
  • Результат: отчёты и API начинают давать одинаковые цифры.
Характеристики:
  • улучшает консистентность бизнес-логики;
  • снижает вероятность расхождения метрик;
  • ускоряет поддержку legacy-кода.
Когда использовать: Для часто переиспользуемых фильтров, JOIN и read-моделей.
Вывод: VIEW — это в первую очередь инструмент качества и поддержки, а не «оптимизация ради оптимизации».

🧱 3. VIEW vs таблица

Новички часто путают VIEW с обычной таблицей, потому что в SELECT они выглядят похоже.
Но архитектурно это разные объекты.
🟢 Если совсем просто: Таблица хранит данные, VIEW хранит запрос.
🎯 Как понять, что этап прошёл успешно: Вы можете объяснить, когда нужен CREATE TABLE, а когда CREATE VIEW.
Назначение: Понять границу между хранением и представлением данных.
Простыми словами: Таблица — «где живут данные», VIEW — «как мы их показываем».
Для новичка: Если нужно физически записывать строки — нужна таблица. Если нужна повторяемая выборка — подходит VIEW.
Аналогия: Таблица — это склад, а VIEW — витрина магазина.
Пример:
CREATE TABLE orders (  id BIGINT PRIMARY KEY,  user_id BIGINT NOT NULL,  status TEXT NOT NULL,  total_amount NUMERIC(12,2) NOT NULL);
CREATE VIEW orders_paid_view ASSELECT  o.id,  o.user_id,  o.total_amountFROM orders oWHERE o.status = 'paid';
🔎 Как это происходит на практике:
  • Контекст: в проекте нужен отдельный «read layer» без копирования данных.
  • Действия: исходные данные хранят в таблицах, отчётную логику выносят в VIEW.
  • Результат: структура хранения и структура чтения разделены.
Характеристики:
  • таблица и VIEW решают разные задачи;
  • VIEW может использовать несколько таблиц;
  • изменение таблиц может потребовать обновления VIEW.
Когда использовать: В любом проекте, где есть повторяемая read-логика.
Вывод: Путать VIEW и таблицу нельзя: это разные уровни модели данных.

🧩 4. Простой рабочий пример

Соберём минимальный кейс, который часто встречается в CRUD-продуктах: нужно вывести «пользователь + число его оплаченных заказов».
Без VIEW такой JOIN/агрегация быстро копируются по коду.
🟢 Если совсем просто: Один VIEW закрывает типовую витрину для API и отчётов.
🎯 Как понять, что этап прошёл успешно: Вы получаете нужный набор данных одним SELECT из представления.
Назначение: Показать практическую пользу VIEW на простом SQL.
Простыми словами: Сначала описываем витрину, потом читаем её как обычную таблицу.
Для новичка: Хороший VIEW имеет чёткое имя и явные поля, чтобы не было «SELECT *» хаоса.
Аналогия: Это как подготовленный endpoint внутри базы данных.
Пример:
CREATE VIEW users_paid_stats_view ASSELECT  u.id AS user_id,  u.email,  COUNT(o.id) AS paid_orders_countFROM users uLEFT JOIN orders o  ON o.user_id = u.id AND o.status = 'paid'GROUP BY u.id, u.email;
SELECT  s.user_id,  s.email,  s.paid_orders_countFROM users_paid_stats_view sORDER BY s.paid_orders_count DESCLIMIT 20;
🔎 Как это происходит на практике:
  • Контекст: админка должна показывать «топ клиентов по paid-заказам».
  • Действия: создают users_paid_stats_view и переиспользуют его в API.
  • Результат: SQL в приложении становится короче и понятнее.
Характеристики:
  • объединяет JOIN + агрегаты в одном месте;
  • уменьшает дубли сложной выборки;
  • даёт стабильный набор колонок для клиентов.
Когда использовать: Для повторяемых dashboard/API-выборок.
Вывод: Даже один простой VIEW заметно улучшает читаемость и поддержку кода.

🚀 5. Materialized view (обзорно)

Materialized view похож на VIEW, но работает иначе: результат запроса сохраняется физически.
Это полезно для тяжёлых отчётов, которые не нужно пересчитывать на каждый запрос.
🟢 Если совсем просто: Обычный VIEW пересчитывается на чтении, materialized view хранит готовый результат.
🎯 Как понять, что этап прошёл успешно: Вы можете выбрать между обычным VIEW и materialized view по требованиям свежести и скорости.
Назначение: Ускорить тяжёлые read-сценарии за счёт предрасчёта данных.
Простыми словами: Это «снимок» результата запроса, который нужно обновлять (REFRESH).
Для новичка: Materialized view даёт скорость, но требует стратегии обновления данных.
Аналогия: Обычный VIEW — готовка по рецепту каждый раз; materialized view — заранее приготовленное блюдо, которое иногда обновляют.
Пример (PostgreSQL):
CREATE MATERIALIZED VIEW sales_daily_mv ASSELECT  DATE_TRUNC('day', o.created_at) AS day_bucket,  SUM(o.total_amount) AS revenueFROM orders oWHERE o.status = 'paid'GROUP BY 1;
REFRESH MATERIALIZED VIEW sales_daily_mv;
🔎 Как это происходит на практике:
  • Контекст: отчёт «выручка по дням» тормозит при онлайн-пересчёте.
  • Действия: делают materialized view и обновляют по расписанию.
  • Результат: отчёты читаются быстро, цена — задержка по свежести.
Характеристики:
  • быстрее чтение тяжёлых агрегатов;
  • нужна отдельная стратегия refresh;
  • актуальность данных зависит от частоты обновления.
Когда использовать: Для тяжёлой аналитики, где допустима небольшая задержка данных.
Вывод: Materialized view — это компромисс «скорость чтения vs свежесть данных».

🧪 6. Мини-сравнение: VIEW vs materialized view

КейсVIEWMaterialized view
Хранение результатаНе хранит отдельноХранит физически
АктуальностьВсегда текущая по базовым таблицамЗависит от refresh
Скорость тяжёлых отчётовМожет быть медленнееОбычно быстрее
ОбслуживаниеПрощеНужен процесс обновления
Вывод: Для свежих онлайн-данных обычно подходит VIEW, для тяжёлой аналитики — materialized view.

🧠 Must-Know (запомнить)

  • VIEW — это сохранённый SELECT, а не таблица с отдельным набором строк.
  • Главная польза VIEW — повторное использование и единообразие read-логики.
  • VIEW часто применяют для API-выборок и отчётных витрин.
  • Не стоит использовать VIEW как «магическое ускорение» без анализа запроса.
  • Materialized view хранит результат физически и требует REFRESH.
  • Materialized view уместен, когда чтение тяжёлое, а задержка свежести допустима.
  • Имена и колонки VIEW должны быть максимально явными для команды.
  • Любые изменения базовой схемы нужно проверять на совместимость с VIEW.
Вывод: Сильный junior должен уверенно различать задачи VIEW, таблиц и materialized view.

❌ Частые мифы

Миф: VIEW всегда ускоряет запросы. ✅ Как правильно: VIEW в первую очередь упрощает логику; производительность зависит от самого запроса и индексов. 📎 Почему это важно: Иначе команда ожидает «бесплатный буст», которого может не быть.
Миф: VIEW хранит свои данные как таблица. ✅ Как правильно: Обычный VIEW хранит определение SQL, а не отдельный физический набор строк. 📎 Почему это важно: Это базовая разница в архитектуре и в ожиданиях по обновлению данных.
Миф: Materialized view всегда лучше обычного VIEW. ✅ Как правильно: Materialized view быстрее на чтении, но требует refresh и даёт задержку актуальности. 📎 Почему это важно: Без учёта свежести данных можно сломать бизнес-метрики.
Миф: Лучше везде использовать SELECT * внутри VIEW. ✅ Как правильно: Явно перечисляйте поля, чтобы контролировать контракт и избежать неожиданных изменений. 📎 Почему это важно: Это упрощает поддержку и снижает риск регрессий.

🎤 Часто спрашивают на собеседованиях

Вопрос: Что такое VIEW в SQL? ✅ Ответ: Это именованное представление на базе SELECT, которое используется как виртуальная таблица для чтения.
Вопрос: Чем VIEW отличается от обычной таблицы? ✅ Ответ: Таблица хранит строки физически, обычный VIEW хранит определение запроса и вычисляется при чтении.
Вопрос: Зачем VIEW в проекте, если можно писать JOIN в коде? ✅ Ответ: Чтобы не дублировать сложные запросы и держать единые бизнес-правила чтения в одном месте.
Вопрос: Когда лучше использовать materialized view? ✅ Ответ: Когда запрос тяжёлый, а небольшая задержка актуальности допустима.
Вопрос: Что такое REFRESH MATERIALIZED VIEW? ✅ Ответ: Это обновление сохранённого результата materialized view из базовых таблиц.
Вопрос: Может ли VIEW заменить нормализацию данных? ✅ Ответ: Нет, VIEW — это слой чтения, а не замена корректной модели хранения.
Вопрос: Нужно ли пересматривать VIEW после изменения схемы таблиц? ✅ Ответ: Да, потому что изменения полей/JOIN-логики могут нарушить контракт представления.

🚨 Типичные ошибки

  • Копировать один и тот же сложный SQL вместо создания VIEW.
  • Считать VIEW инструментом «автоматического ускорения».
  • Делать SELECT * и терять контроль над контрактом представления.
  • Путать обычный VIEW и materialized view.
  • Использовать materialized view без стратегии refresh.
  • Не тестировать VIEW после миграций схемы.
Вывод: Ошибки вокруг VIEW чаще связаны с ожиданиями и дисциплиной поддержки, а не со сложностью синтаксиса.

✅ Best Practices

  • Создавайте VIEW для реально повторяющихся бизнес-выборок.
  • Давайте представлениям понятные имена (users_active_view, orders_paid_view).
  • Явно перечисляйте колонки и избегайте SELECT *.
  • Документируйте назначение каждого VIEW в схеме/репозитории.
  • Для materialized view заранее определяйте частоту refresh и SLA по свежести.
  • После изменений таблиц проверяйте зависимые VIEW интеграционными тестами.
  • Не прячьте критичную бизнес-логику в «чёрный ящик» без описания.
Вывод: Хороший VIEW — это прозрачный и поддерживаемый контракт чтения для всей команды.

🧾 Заключение

VIEW — одна из самых практичных тем для junior: она быстро даёт эффект в читаемости SQL и качестве поддержки.
Если вы понимаете, чем VIEW отличается от таблицы и когда нужен materialized view, вы уже делаете архитектуру чтения зрелее.
Вывод: Используйте VIEW как инструмент стандартизации запросов, а materialized view — как осознанную оптимизацию под тяжёлую аналитику.
🎯

Проверьте знания

Закрепите материал — пройдите тест по теме «БЛОК 11. Объекты БД — 26. VIEW (представления)»

Пройти тест →