Схема - простір імен усередині бази. Таблиці billing.invoices і public.invoices - різні об'єкти. За замовчуванням усе створюється в схемі public.
CREATE SCHEMA billing;
CREATE TABLE billing.invoices (...);
search_path - список схем, у яких PostgreSQL шукає об'єкт, названий без схеми:
SHOW search_path; -- "$user", public
SET search_path = billing, public;
SELECT * FROM invoices; -- billing.invoices
"$user" - схема з ім'ям поточного користувача, якщо вона існує.
Навіщо схеми:
- модулі застосунку:
billing,analytics,audit- окремі права й зрозуміла структура; - мультитенантність «схема на тенанта»: однакові таблиці в
tenant_42,tenant_43, перемикання черезsearch_path. Ізоляція краща за колонкуtenant_id, але тисячі схем ускладнюють міграції й навантажують каталог; - розширення окремо від даних (
CREATE EXTENSION pg_trgm SCHEMA extensions); - права:
GRANT USAGE ON SCHEMA analytics TO bi_reader- доступ до всієї групи таблиць.
Безпека - головне про search_path:
1. Підміна об'єктів. Якщо користувач може створювати об'єкти в схемі, що стоїть у search_path раніше за потрібну, він може «перехопити» ім'я таблиці чи функції. Саме тому з PostgreSQL 15 звичайні користувачі не можуть створювати об'єкти в public за замовчуванням (раніше могли всі).
2. Функції з SECURITY DEFINER виконуються з правами власника. Якщо в них не зафіксовано search_path, зловмисник створює функцію з тим самим ім'ям у своїй схемі - і вона виконується з правами власника:
CREATE FUNCTION billing.close_period() RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = billing, pg_temp
AS $$ ... $$;
pg_temp останнім - щоб тимчасові об'єкти сесії не могли нічого підмінити.
У Laravel:
'search_path' => 'public'у конфігурації з'єднанняpgsql(ключsearch_path);- міграції й моделі можуть звертатися до схеми явно:
protected $table = 'billing.invoices'; - PgBouncer у режимі transaction pooling:
SET search_pathна рівні сесії «протікає» між клієнтами, що ділять з'єднання. Безпечніше задаватиsearch_pathдля ролі (ALTER ROLE app SET search_path = ...) чи використовувати повні імена.
Правило: у продакшен-базі користувач застосунку не повинен мати права CREATE у схемах, які є в search_path інших ролей.