Тома и представления
Том — именованная область хранения данных (диск, раздел, volume в Docker), представление (вьюха) — сохранённый SQL-запрос, который выглядит как таблица.
Что такое тома и представления
Это два независимых термина, которые объединяет только одно — оба дают имя чему-то, устроенному не так, как выглядит. Том (volume) — именованная область хранения, к которой обращаются как к диску. Представление (view, «вьюха») — сохранённый SQL-запрос, к которому обращаются как к таблице. Ничего общего между ними нет, и ниже они разобраны по отдельности.
Что такое том
Том (volume) — именованная область хранения данных, которая для системы выглядит как отдельный диск. В зависимости от контекста слово означает разные вещи:
| Контекст | Что такое том |
|---|---|
| Диски и разделы | Логический раздел: C: в Windows, /dev/sda1 в Linux |
| LVM | Логический том поверх группы физических дисков |
| СХД | LUN — кусок ёмкости массива, отданный серверу |
| Docker | Область данных, живущая отдельно от контейнера |
| Kubernetes | Volume и PersistentVolume, подключаемые к подам |
Общий смысл везде один: том отвязывает данные от конкретного носителя. Физически он может лежать на одном диске, на RAID-массиве из десяти дисков или на сетевом хранилище — потребитель видит просто устройство.
Тома в Docker
Самый частый контекст, в котором разработчик встречает слово. Контейнер эфемерен: удалили — данные внутри исчезли. Том решает эту проблему.
docker volume create pgdata
docker run -d --name db \
-v pgdata:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=secret \
postgres:16
docker rm -f db # контейнер удалён
docker run -d --name db2 -v pgdata:/var/lib/postgresql/data postgres:16
# данные на месте — том пережил контейнер
docker volume ls
docker volume inspect pgdata # где физически лежит
docker volume prune # удалить тома, которые никем не используются
Named volume против bind mount: -v pgdata:/data — том под управлением Docker, -v /home/user/data:/data — просто папка хоста. Для баз данных выбирают именованный том; bind mount удобен в разработке, чтобы править код без пересборки образа.
Осторожно с docker volume prune и docker-compose down -v: обе команды удаляют тома, и вместе с ними базу данных.
LVM
pvcreate /dev/sdb /dev/sdc # физические тома
vgcreate data_vg /dev/sdb /dev/sdc # группа томов
lvcreate -L 500G -n db_lv data_vg # логический том
mkfs.ext4 /dev/data_vg/db_lv
mount /dev/data_vg/db_lv /var/lib/postgresql
lvextend -L +200G -r /dev/data_vg/db_lv # расширить на живой ФС
Ценность LVM в последней строке: том расширяется без остановки и переразметки, а место берётся из пула дисков. Плюс снапшоты — мгновенный снимок тома перед рискованным обновлением.
Что такое представление (вьюха)
Представление (view, «вьюха») — сохранённый в базе SQL-запрос, к которому можно обращаться как к таблице. Своих данных у него нет: при каждом обращении СУБД подставляет и выполняет запрос заново.
CREATE VIEW active_customers AS
SELECT u.id, u.email, count(o.id) AS orders, sum(o.total) AS revenue
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE u.deleted_at IS NULL
GROUP BY u.id, u.email;
SELECT * FROM active_customers WHERE revenue > 100000;
Зачем нужны:
- Спрятать сложность. Запрос с пятью
JOINпишется один раз, а не копируется по коду. - Разграничить доступ. Аналитику дают права на представление без зарплат и телефонов, а не на исходную таблицу — это применение RBAC на уровне данных.
- Совместимость. Схема поменялась, а представление сохраняет старый интерфейс для legacy-кода.
Чего вьюха не делает — не ускоряет запрос. Это подстановка текста, а не кеш: SELECT * FROM active_customers каждый раз выполняет всю группировку заново. Распространённое заблуждение — рассчитывать, что вынос тяжёлого запроса во view его оптимизирует.
Материализованное представление
CREATE MATERIALIZED VIEW revenue_by_day AS
SELECT date_trunc('day', created_at) AS day, sum(total) AS revenue
FROM orders GROUP BY 1;
CREATE UNIQUE INDEX ON revenue_by_day (day); -- нужен для CONCURRENTLY
REFRESH MATERIALIZED VIEW CONCURRENTLY revenue_by_day; -- без блокировки чтения
В отличие от обычного, материализованное представление хранит результат на диске. Запросы к нему мгновенны, по нему строят индексы — но данные устаревают до следующего REFRESH, который запускают по расписанию.
Это рабочий приём для дашбордов и отчётов: тяжёлая агрегация считается раз в час, а не при каждом открытии страницы. Если данных становится слишком много, следующий шаг — вынести аналитику в ClickHouse.
| View | Materialized view | |
|---|---|---|
| Хранит данные | Нет | Да |
| Актуальность | Всегда свежие | На момент REFRESH |
| Скорость чтения | Как исходный запрос | Как обычная таблица |
| Индексы | Нельзя | Можно |
Обновляемые представления
Простое представление без агрегатов и JOIN в PostgreSQL можно менять напрямую — INSERT и UPDATE уйдут в исходную таблицу. Как только появляются GROUP BY, DISTINCT или несколько таблиц, автоматически это не работает: нужен триггер INSTEAD OF.
Связанные термины
- SQL — язык, на котором создаются представления
- Базы данных — где живут вьюхи
- Docker — тома для данных контейнеров
- persistent volume — тома в Kubernetes
- СХД — тома и LUN на уровне хранилища
- snapshot — снимки томов
Готовы запустить GPU-задачу?
Запустить GPU-сервер