Перейти к содержанию

Схемы и имена объектов

Теперь мы умеем указать сервер и базу. Внутри учебной базы находятся три таблицы, но их полные имена начинаются с catalog. Это не случайный префикс имени файла. PostgreSQL позволяет группировать объекты в схемы, а запрос может явно выбрать, в какой схеме находится нужная таблица.

Разберём пространство имён на каталоге курсов. Используем PostgreSQL 17.11 и самостоятельный снимок catalog-db/lesson-03 из архива серии. SQL не запускался; ожидаемое состояние описано по общему договору. Перед будущим восстановлением помните, что reset.sql разрушительно пересоздаёт учебную схему только в изолированной базе.

Квалифицированное имя

В записи catalog.courses первая часть — схема, вторая — таблица. База выбирается при подключении, поэтому полное имя здесь не содержит произвольную базу на другом сервере. Схема помогает отличить объекты, которые могли бы иметь одинаковые короткие имена. Например, административный модуль и учебный каталог могут оба использовать таблицу courses, если они помещены в разные пространства имён.

У схемы нет собственной копии соединения. Один клиент может обращаться к доступным объектам разных схем выбранной базы. Следовательно, схема удобна для организации, но сама по себе не равна отдельной базе или отдельному серверу. Для экспериментов серии изоляцию обеспечивает учебная среда; префикс catalog лишь делает область SQL явной.

Начнём с чтения:

SELECT id, slug, title
FROM catalog.topics
ORDER BY id;

Ожидаются четыре темы: фронтенд, публикация, бэкенд и дизайн. Их порядок задан числовым ключом. Названия хранятся как данные и могут быть кириллическими. Имена SQL-объектов в этой серии состоят из латиницы и подчёркиваний, чтобы не смешивать пользовательское название с техническим идентификатором.

Такой выбор не означает запрет кириллицы в PostgreSQL. Он уменьшает количество деталей, которые нужно удерживать при изучении отношений. Важно соблюдать единый договор: topics — имя таблицы, title — имя колонки, «Фронтенд» — значение в строке. Кавычки в SQL предназначены для разных категорий, и эта разница становится заметна при первом переименовании.

Короткое имя и search_path

Когда в запросе указано только courses, сервер ищет объект по текущему search_path. Список определяет порядок просмотра схем. Если там нет catalog, короткое имя может не разрешиться. Если в более ранней схеме лежит другая courses, разрешится другой объект. Это поведение описано в документации схем PostgreSQL.

В учебном чтении можно посмотреть настройку, ничего не меняя:

SHOW search_path;
SELECT current_schema();

Ответ зависит от конфигурации роли и базы. Не приписывайте ему фиксированное значение только потому, что файл урока одинаков. current_schema() показывает первую существующую схему пути поиска, а не название схемы каждой таблицы, которую клиент когда-либо читал. Если запрос обращается к catalog.courses явно, он не обязан совпадать с этим значением.

Рассмотрим изменение как отдельный мысленный опыт. Если установить search_path в catalog, короткий запрос к courses станет удобнее. Но эта настройка относится к сессии или к принятой конфигурации, а не записывается магически в каждый SQL-файл. Передача запроса другому клиенту может вернуть прежнюю неоднозначность. Поэтому снимки серии продолжают использовать квалифицированные имена.

Наличие доступной для чужого создания схемы в пути поиска заслуживает внимания при проектировании приложения. Человек, способный создать объект с подходящим именем, может изменить разрешение короткого имени. Явная квалификация основных таблиц делает намерение понятнее, но полноценная политика прав рассматривает также функции, операторы и весь набор доступных объектов. В начальном каталоге нам достаточно не доверять незнакомой схеме ради удобства сокращений.

Кавычки и регистр

Неквалифицированный SQL-идентификатор без двойных кавычек PostgreSQL приводит к нижнему регистру. Двойные кавычки сохраняют точное написание. Строковый литерал записывается в одинарных кавычках. Эти три вещи похожи визуально, но выполняют разные действия. Например, 'courses' представляет текстовое значение, а courses в позиции таблицы обозначает объект.

В серии не создаётся таблица "Courses". Иначе при каждом обращении пришлось бы сохранять кавычки и регистр. Договор нижнего регистра удобен ещё и для миграций: редактор видит одинаковое имя в SQL, документации и схеме без скрытого различия одной заглавной буквы.

Сравним чтение значения и описание структуры:

SELECT 'catalog.courses' AS object_name;
SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema = 'catalog'
ORDER BY table_name;

Первый запрос возвращает строку независимо от существования таблицы. Второй обращается к системному представлению метаданных и должен перечислить courses, lessons, topics в учебной схеме. Именно поэтому успешное получение текста 'catalog.courses' нельзя считать проверкой подготовленного снимка. Результат определяется положением слова в языке, а не его похожестью на имя.

Метаданные также учитывают видимость объектов для текущей роли. Здесь учебная роль владеет созданными таблицами и должна видеть их. На другом сервере отсутствие строки в таком представлении требует проверки прав и подключения, а не немедленного вывода о физическом отсутствии данных.

Схема и жизненный цикл

Файл восстановления содержит DROP SCHEMA ... CASCADE. Такая команда удаляет схему вместе с зависимыми объектами, а не очищает только один список карточек. В нашем снимке это сознательное восстановление известного исходного состояния. На рабочем приложении подобный приём уничтожил бы содержимое каталога, поэтому его нельзя превращать в способ обычного обновления сайта.

Сравните три действия: добавить курс, изменить колонку, удалить схему. Они затрагивают разные уровни. Добавление работает со строками. Изменение колонки меняет структуру таблицы. Удаление схемы убирает целую область объектов и связей. Слово «обновить» в разговоре может обозначать любое из них, но SQL должен фиксировать точную операцию.

В самостоятельном снимке начальные таблицы уже существуют после reset. lesson.sql лишь читает темы, путь поиска и список объектов. Поэтому повторение чтения не меняет результат. Повторение reset, напротив, снова уничтожает внесённые вами учебные изменения. Такие два файла держатся отдельно, чтобы операция чтения не маскировала восстановление структуры.

Имена приложения и имена SQL

Папка проекта catalog-db не создаёт схему сама по себе. Точно так же Python-модуль с названием catalog не сообщает PostgreSQL, где искать таблицы. Файловое пространство, пространство имён языка приложения и пространство имён базы организуются разными механизмами. Их названия можно согласовать ради удобства человека, но связь появляется только через явные определения и запросы.

Увидев в ошибке слово courses, полезно восстановить полный контекст: какая база выбрана, какая роль подключена, какое имя отправлено и какой путь поиска действует. Начинать сразу с повторного CREATE TABLE опасно для понимания: можно создать вторую похожую таблицу в другой схеме и ещё сильнее скрыть исходную причину.

Метаданные из снимка дают предметный ориентир: в catalog должны быть ровно три базовые таблицы учебного договора. Если вы экспериментировали с дополнительными объектами, это уже новое состояние вашей базы. Reset вернёт исходное, но уничтожит именно эти изменения, поэтому сначала прочитайте его текст и сохраните нужную самостоятельную работу отдельно.

Попробуйте при будущем ручном изучении заменить в запросе catalog.topics на короткое topics, предварительно посмотрев search_path. Если короткое имя не найдено, объяснение должно связывать ошибку с разрешением имени. Если найдено, сравните схему выбранного объекта, а не только похожий набор колонок. После этого верните явную запись: следующие уроки будут обсуждать типы и ограничения именно наших трёх таблиц, не полагаясь на случайную конфигурацию клиента.

Оглавление курса.