PostgreSQLJuniorTechnical

Что такое схемы (schemas) PostgreSQL и как они связаны с базами данных?

Схема — пространство имён внутри базы данных, содержащее таблицы, функции и другие объекты. Одна БД может иметь множество схем; search_path определяет, в каком порядке PostgreSQL ищет объекты без явного префикса.

Схемы (schemas) в PostgreSQL

Схема — это пространство имён внутри базы данных. Одна база данных содержит несколько схем; схема содержит таблицы, представления, функции, последовательности и другие объекты. Это позволяет логически разделять объекты без создания отдельных баз данных.

Связь: кластер → база данных → схема → объекты

  • Кластер — один запущенный экземпляр PostgreSQL (один порт). Содержит несколько баз данных.
  • База данных — изолированное пространство; транзакции не пересекают границы БД. Подключение всегда к одной БД.
  • Схема — пространство имён внутри БД; объекты из разных схем одной БД можно объединять в одном запросе.

Работа со схемами

-- Создать схему
CREATE SCHEMA sales;
CREATE SCHEMA analytics;

-- Создать таблицу в конкретной схеме
CREATE TABLE sales.orders (
    id      bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    amount  numeric,
    created_at timestamptz DEFAULT now()
);

CREATE TABLE analytics.orders_summary (
    day     date,
    revenue numeric
);

-- Обращение к объектам разных схем в одном запросе
SELECT s.id, s.amount, a.revenue
FROM sales.orders s
JOIN analytics.orders_summary a ON DATE_TRUNC('day', s.created_at) = a.day;

search_path

Переменная search_path определяет порядок, в котором PostgreSQL ищет объекты без явного префикса схемы. По умолчанию: "$user", public — сначала схема с именем текущего пользователя, затем public.

-- Текущий search_path
SHOW search_path;

-- Изменить для сессии
SET search_path TO sales, public;

-- Теперь можно обращаться без префикса:
SELECT * FROM orders;  -- ищет sales.orders, затем public.orders

-- Установить постоянно для роли
ALTER ROLE app_user SET search_path TO myapp, public;

-- Установить для базы данных
ALTER DATABASE mydb SET search_path TO myapp, public;

Права доступа

-- Создать роль и выдать доступ к схеме
CREATE ROLE readonly_user LOGIN PASSWORD 'secret';

-- Право на использование схемы (USAGE)
GRANT USAGE ON SCHEMA sales TO readonly_user;

-- Право на чтение всех существующих таблиц
GRANT SELECT ON ALL TABLES IN SCHEMA sales TO readonly_user;

-- Автоматически выдавать права на будущие таблицы
ALTER DEFAULT PRIVILEGES IN SCHEMA sales
    GRANT SELECT ON TABLES TO readonly_user;

-- Удалить схему вместе с объектами
DROP SCHEMA analytics CASCADE;

Схема public и безопасность

-- PostgreSQL 15+: по умолчанию CREATE в public запрещён для обычных ролей
-- Ранее любой пользователь мог создавать объекты в public
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

-- Проверить объекты в схеме
SELECT table_name, table_type
FROM information_schema.tables
WHERE table_schema = 'sales';

-- Все схемы в базе
SELECT nspname, nspowner::regrole
FROM pg_namespace
ORDER BY nspname;

Практические паттерны

  • Multi-tenancy: каждый клиент в своей схеме (tenant_123); search_path переключается в начале сессии.
  • Версионирование API: v1.users, v2.users — разные схемы для разных версий представлений.
  • Изоляция микросервисов: несколько сервисов в одной БД с разными схемами и ролями.

Подводные камни

  • Забытый GRANT USAGE ON SCHEMA: пользователь с правами на таблицу, но без прав на схему, получит ERROR: permission denied for schema.
  • Схемы не изолируют транзакции и не пересекают границы базы данных — dblink или postgres_fdw нужны для cross-database запросов.
  • search_path уязвимость: если public входит в search_path и непривилегированные пользователи могут создавать объекты в public, злоумышленник может подменить функцию и перехватить вызовы. Выполните REVOKE CREATE ON SCHEMA public FROM PUBLIC.
  • Миграции в multi-tenant схемах сложнее: нужно применять DDL для каждой схемы отдельно; инструменты вроде Flyway/Liquibase поддерживают это, но требуют настройки.
  • Производительность: схемы не добавляют overhead на запросы, но pg_dump с --schema требует явного указания имени — при переименовании схемы все скрипты нужно обновлять.
  • Объекты в pg_catalog и information_schema — системные схемы PostgreSQL; не создавайте объекты с такими именами.

Common mistakes

  • Отвечать про schemas как про абстрактный SQL без учета MVCC, WAL, planner или конкретной версии PostgreSQL.
  • Переносить поведение MySQL или ClickHouse на PostgreSQL без проверки документации.
  • Не связывать механизм с последствиями для индексов, транзакций, блокировок или эксплуатации.
  • Показывать синтаксис, который не поддерживается PostgreSQL.

What the interviewer is testing

  • Кандидат объясняет schemas через реальный механизм PostgreSQL, а не общими словами.
  • Приводит корректный SQL или диагностический запрос для этой СУБД.
  • Называет ограничения, версионные отличия или эксплуатационные последствия.
  • Связывает ответ с проектированием приложения, производительностью, надежностью или безопасностью.

Sources

Related topics