Что такое schema в PostgreSQL?
Что такое schema в PostgreSQL
Schema (схема) — это логический контейнер внутри базы данных PostgreSQL, который группирует связанные объекты: таблицы, индексы, последовательности, представления, функции и типы данных. Схема не является физическим разделением данных — это исключительно пространство имён.
Зачем нужны схемы
Схемы решают несколько практических задач:
- Организация объектов — можно разделить таблицы по модулям приложения:
auth.users,billing.invoices,catalog.products - Разграничение прав — схема является единицей управления доступом: одному пользователю можно дать права только на схему
public, другому — наadmin - Изоляция клиентов — в мультитенантных приложениях каждый клиент получает свою схему с одинаковой структурой таблиц
- Избежание конфликтов имён — две схемы могут содержать таблицы с одинаковыми именами без конфликтов
Схема public по умолчанию
При создании базы данных PostgreSQL автоматически создаёт схему public. Если схема не указана явно, объекты создаются и ищутся в public. Это поведение определяется переменной search_path.
search_path
search_path — это список схем, в которых PostgreSQL ищет объекты, когда имя указано без префикса схемы. По умолчанию значение "$user", public, что означает: сначала ищем в схеме с именем текущего пользователя, затем в public.
-- Посмотреть текущий search_path
SHOW search_path;
-- Изменить search_path для сессии
SET search_path TO billing, public;
-- Изменить search_path для конкретного пользователя
ALTER ROLE app_user SET search_path TO app, public;
Основные операции со схемами
-- Создать схему
CREATE SCHEMA billing;
-- Создать схему и сразу назначить владельца
CREATE SCHEMA billing AUTHORIZATION billing_user;
-- Создать таблицу в конкретной схеме
CREATE TABLE billing.invoices (
id SERIAL PRIMARY KEY,
amount NUMERIC(10, 2) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Обратиться к таблице с указанием схемы
SELECT * FROM billing.invoices;
-- Переименовать схему
ALTER SCHEMA billing RENAME TO payments;
-- Удалить схему (только если пустая)
DROP SCHEMA billing;
-- Удалить схему вместе со всеми объектами
DROP SCHEMA billing CASCADE;
Управление правами на схему
-- Дать пользователю право видеть объекты схемы
GRANT USAGE ON SCHEMA billing TO app_user;
-- Дать права на все таблицы схемы
GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA billing TO app_user;
-- Дать права на будущие таблицы схемы
ALTER DEFAULT PRIVILEGES IN SCHEMA billing
GRANT SELECT ON TABLES TO readonly_user;
Важный нюанс безопасности
С PostgreSQL 15 схема public больше не доступна всем пользователям по умолчанию. Право CREATE в public теперь нужно выдавать явно, что снижает риск непреднамеренного создания объектов чужими пользователями.
Что хочет услышать интервьюер
Понимание того, что schema — это пространство имён внутри базы данных, а не отдельная база
Знание схемы public как схемы по умолчанию и роли search_path
Умение создавать схему и обращаться к объектам через префикс (schema.table)
Понимание практических сценариев применения: мультитенантность, разделение модулей, управление правами
Знание базовых команд: CREATE SCHEMA, DROP SCHEMA, GRANT USAGE
Пример: Создание схем и работа с объектами
-- Создаём отдельные схемы для модулей приложения
CREATE SCHEMA auth;
CREATE SCHEMA billing;
CREATE SCHEMA catalog;
-- Создаём таблицы в нужных схемах
CREATE TABLE auth.users (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULL
);
CREATE TABLE billing.invoices (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES auth.users(id), -- ссылка на другую схему
amount NUMERIC(10, 2) NOT NULL
);
-- Запрос с явным указанием схемы
SELECT u.email, i.amount
FROM auth.users u
JOIN billing.invoices i ON i.user_id = u.id;
-- Настраиваем search_path чтобы не писать префикс каждый раз
SET search_path TO auth, billing, public;
-- Теперь можно обращаться без префикса
SELECT * FROM users; -- найдёт auth.users
SELECT * FROM invoices; -- найдёт billing.invoices
Пример: Мультитенантность через схемы
-- Каждый клиент получает свою схему с одинаковой структурой
CREATE SCHEMA tenant_acme;
CREATE SCHEMA tenant_globex;
-- Одинаковая структура в каждой схеме
CREATE TABLE tenant_acme.orders (id SERIAL PRIMARY KEY, total NUMERIC);
CREATE TABLE tenant_globex.orders (id SERIAL PRIMARY KEY, total NUMERIC);
-- Переключаемся на нужного клиента через search_path
SET search_path TO tenant_acme;
SELECT * FROM orders; -- данные только клиента ACME
SET search_path TO tenant_globex;
SELECT * FROM orders; -- данные только клиента Globex
Типичные ошибки
Путают schema с отдельной базой данных — schema существует внутри одной базы и не изолирует соединения
Не знают про search_path и удивляются, почему одна и та же таблица видна или не видна в зависимости от контекста
Забывают выдать GRANT USAGE ON SCHEMA перед тем как дать права на таблицы — без USAGE пользователь не может даже «войти» в схему
Используют DROP SCHEMA без CASCADE и не понимают, почему команда завершается с ошибкой, если схема не пуста
Считают, что схема public автоматически доступна всем пользователям во всех версиях PostgreSQL, не зная об изменении в PG 15


