Как влияет создание view с SELECT * на занимаемое место в базе данных?
Что проверяют
Понимаете ли вы, что обычное представление хранит только запрос, и отличаете ли его от материализованного. Для QA к этому добавляется практическая сторона: что сломается в представлении после миграции таблицы. Следом часто спрашивают, как посмотреть размер объектов в базе.
Как отвечать
Обычный CREATE VIEW сохраняет в системном каталоге только определение запроса. Данных в нём нет, при каждом обращении база выполняет запрос к исходным таблицам. Такое представление занимает килобайты метаданных, и SELECT * здесь ничего не меняет.
Место занимают представления, которые хранят результат:
- материализованное представление в PostgreSQL и Oracle:
CREATE MATERIALIZED VIEWсохраняет выборку на диск, обновляют её черезREFRESH MATERIALIZED VIEW. СSELECT *там лежит копия всех колонок, включая ненужные; - индексированное представление в SQL Server: обычный view с
WITH SCHEMABINDINGи уникальным кластерным индексом. Данные хранятся в индексе, аSELECT *там запрещён, колонки нужно перечислить явно.
Проверить можно в PostgreSQL: pg_total_relation_size() на материализованном представлении покажет реальный размер на диске, а у обычного представления файла с данными нет вовсе.
Главный подвох SELECT * не в месте, а в поведении. В PostgreSQL и MySQL звёздочка раскрывается в список колонок в момент создания. Добавили колонку в таблицу, в представлении её не будет, пока его не пересоздадут. Удалить колонку, которая попала в представление, PostgreSQL без CASCADE не даст. В SQL Server обычное представление после изменения таблицы может отдавать устаревшие метаданные, пока не вызвать sp_refreshview.
Вывод для тестировщика: после миграции проверяйте, что представления отдают ожидаемый набор колонок, а отчёты на их основе не потеряли поля.
Где спотыкаются
Отвечают, что представление копирует таблицу и удваивает место. Это верно только для материализованного варианта.
Забывают о материализованных представлениях и уверенно говорят «ноль байт» в любом случае.
Считают, что представление со SELECT * само подхватит новые колонки. На деле набор колонок фиксируется при создании.