Схемы

5.7. Схемы

Кластер баз данных PostgreSQL содержит одну или более баз данных. Пользователи и группы пользователей являются общими внутри этого кластера, но прочие данные являются общими только внутри базы данных. Все клиентские подключения к серверу могут иметь доступ только к данным в одной базе данных: той, которая задана в параметрах подключения.

Note: Пользователям кластера нет необходимости иметь привилегию для доступа к любой базе данных кластера. Общие имена пользователей для кластера означают, что в двух базах данных в одном кластетере не может быть другого пользователя, скажем с именем joe, но СУБД можно настроить так, что разрешить пользователю joe доступ только к некоторым базам данных кластера.

База данных содержит одну или более именованных схем, которые содержат таблицы. Схемы также содержат и други виды именованных объектов, включая типы данных, функции и операторы. То же самое имя объекта может без какого-либо конфликта использоваться в других схемах, например, и схема schema1 и myschema могут содержат таблицы с именем mytable. В отличие от баз данных, схемы жёстко не разделяются: пользователь может получить доступ к объектам в любой схеме в пределах базы данных, к которой он подключён, если у него есть соответствующие привилегии.

Существует несколько причин, почему вы можете захотеть использовать схемы:

  • Чтобы разрешить нескольким пользователям использовать одну базу данных, не смешивая их данные.

  • Чтобы организовать объекты базы данных в логические группы, для того чтобы сделать их более прозрачными в управлении.

  • Разные приложения могут быть размещены в отдельных схемах, чтобы не было конфликтов в использовании имён или других объектов.

Схемы являются аналогами каталогов в операционной системе, за исключением того, что схемы не могут быть вложенными.

5.7.1. Создание схемы

Чтобы создать схему, используйте команду CREATE SCHEMA с указанием выбранного вами имени. Например:

CREATE SCHEMA myschema;

Чтобы создать объект в схеме или получить к нему доступ, необходимо указать полное имя, которое состоит из имени схемы и имени таблицы, которые отделяются друг от друга точкой:

схема.таблица

Это работает везде, где необходимо указывать имя таблицы, включая команды модификации таблиц и команды доступа к данными, о которых рассказывалось в предыдущих главах. (Для краткости мы будем говорить только о таблицах, хотя те же самые идеи применимы и к другим видам объектов, таким как типы данных и функции.)

Фактически, можно также использовать более общий синтаксис:

база.схема.таблица

но его наличие необходимо только для проформы, для соответствия стандарту SQL. Если вы указываете имя базы данных, оно должно совпадать с той базой данных, к которой вы подключились.

Так, для создания таблицы в новой схеме, используйте

CREATE TABLE myschema.mytable (
 ...
);

Чтобы удалить схему, если она пуста (все объекты внутри схемы удалены) используйте

DROP SCHEMA myschema;

Чтобы удалить схему, включая все содержащиеся внутри неё объекты, используйте

DROP SCHEMA myschema CASCADE;

Подробности о том как это работает см. в Section 5.12.

Часто вы будете хотеть создать схему, владелецем которой является кто-то другой (поскольку это один из способов ограничить активность ваших пользователей в пределах назначенных им пространств имён). Вот синтакс, который позволит вам сделать это:

CREATE SCHEMA имя_схемы AUTHORIZATION имя_пользователя;

Вы даже можете опустить имя схемы и в этом случае имя схемы будет установлено такое же как и имя пользователя. О том как этим можно воспользоваться см. в Section 5.7.6.

Имена схем, которые начинаются на pg_ являются зарезервированными для системных целей и не могут быть созданы пользователями.

5.7.2. Схема public

В предыдущих секциях мы создавали таблицы без указания имён схем. По умолчанию, такие таблицы (и другие объекты) автоматически помещаются в схему с именем "public". Каждая новая база данных содержит такую схему. Таким образом, следующие примеры эквивалентны:

CREATE TABLE products ( ... );

и

CREATE TABLE public.products ( ... );

5.7.3. Путь поиска схемы

Полные имена довольно утомительно писать и часто в приложении лучше бывает нигде не привязываться к отдельному имени схемы. Таким образом на таблицы ссылаются через неполные имена, которые содержат только имя таблицы. СУБД определяет какая таблица имеется в виду с помощью пути поиска, который является списком схем, в которых осуществляется поиск. Первая совпавшая таблица в пути поиска считается той, которая запрашивалась. Если совпадающих имён в пути поиска не найдено, будет выдана ошибка, даже если совпадающее имя таблицы существует в других схемах текущей базы данных.

Первая схема в пути поиска называется текущей схемой. Кроме того, что текущая схема будет находится первой, она также является схемой, где будут создаваться новые таблицы командой CREATE TABLE, в которой не указано имя схемы.

Чтобы посмотреть текущий путь поиска, используйте команду:

SHOW search_path;

В случае настроек по умолчанию, она возвращает:

 search_path
--------------
 "$user",public

Первый элемент говорит, что поиск должен производится в схеме с таким же именем как и у текущего пользователя. Если такой схемы не существует, данный элемент игнорируется. Второй элемент указывает на схему public, которую мы уже рассматривали.

Первая существующая схема в пути поиска является местоположением по умолчанию, для создания новых объектов. Именно по этой причине, по умолчанию объекты создаются в схеме public. Когда на объекты ссылаются из любых других контекстов без указания схемы (модификация таблиц, данных или команды запросов) происходит перебор схем в пути поиска пока не будет найден совпавший объект. Следовательно, в конфигурации по умолчанию, все операции без указания имени схемы снова указывают только на схему public.

Чтобы поместить новую схему в путь поисках, используйте команду:

SET search_path TO myschema,public;

(Здесь мы опустили $user, потому что эта схема в данный момент нам не нужна.) И после этого, мы получаем доступ к таблице без указания схемы:

DROP TABLE mytable;

Также, поскольку myschema является первым элементом в пути поиска, именно в ней по умолчанию будут создаваться новые объекты.

Мы также можем написать:

SET search_path TO myschema;

Тогда мы не сможем больше обращаться к схеме public без явного указания имени. В схеме public не существует ничего особенного, кроме того, что она существует по умолчанию. Её можно даже удалить.

Другие способы манипулирования путём поиска схем см. в Section 9.23.

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

OPERATOR(схема.оператор)

Это необходимо для избежания неоднозначностей в синтаксе. Вот пример:

SELECT 3 OPERATOR(pg_catalog.+) 4;

На практике обычно для операторов используется путь поиска, так что вам не придётся писать что-либо так некрасиво как в данном примере.

5.7.4. Схемы и привилегии

По умолчанию, пользователи не имеют доступа к любым объектам в тех схемах, для которых они не являются владельцами. Чтобы у них был доступ, владелец схемы должен предоставить им привилегию USAGE на схему. Чтобы разрешить пользователям использование объектов в схеме, им необходимо предоставить дополнительные привилегии, соответственно для каждого объекта.

Пользователю также можно разрешить создавать объекты в какой-либо другой схеме. Для этого ему нужно предоставить привилегию CREATE на схему. Заметим, что по умолчанию, для схемы public привилегии CREATE и USAGE имеет любой пользователь. Это позволяет всем подключенным к базе данных пользователям, создавать объекты в схеме public. Если вы не хотите разрешать это, вы можете отобрать данную привилегию:

REVOKE CREATE ON SCHEMA public FROM PUBLIC;

(В этой команде при первом появлении "public" означает схему, а при втором означает "каждый пользователь". При первом появлении — это идентификатор, а при втором — ключевое слово, поэтому они и записываются в разных регистрах; согласно рекомендациям из Section 4.1.1.)

5.7.5. Схема системного каталога

В дополнение к схеме public и схемам, которые определяются пользователем, каждая база данных содержит схему pg_catalog, которая содержит системные таблицы и все встроенные типы данных, функции и операторы. pg_catalog всегда является эффективной частью пути поиска. Если эта схема не указывается явно в пути поиска, то она всё-равно неявно используется при поиске перед схемами, указанными в пути поиска. Однако, вы можете явно поместить схему pg_catalog в конец вашего пути поиска, если хотите, чтобы имена, определённые пользователем перекрывали встроенные имена.

В PostgreSQL до версии 7.3, имена таблиц, начинавшиеся с pg_ были зарезервированы. Теперь этого больше нет: если хотите, вы можете создавать такие имена таблиц, в любой несистемной схеме. Однако, лучше всё-таки продолжать избегать таких имён, чтобы быть уверенным в невозможности конфликтов по именам, если в будущем, в какой-либо версии появится системная таблица с таким же именем как и ваша. (С путём поиска по умолчанию, неполное имя вашей таблицы будет распознано как системная таблица.) Системные таблицы будут продолжать следовать соглашению по именам, начинающимся с pg_, так что они не будут конфликтовать с неполными именами пользовательских таблиц, если пользователи будут избегать использования приставки pg_.

5.7.6. Примеры использования

Схемы могут быть использованы для организации ваших данных во многих случаях. Существует несколько рекомендуемых вариантов использования схем, которые поддерживаются в конфигурации по умолчанию:

  • Если вы не создаёте никаких схем, то все пользователи неявно получают доступ к схеме public. Это симулирует ситуацию, когда схемы недоступны никому. Такая стратегия рекомендуется в основном, когда в базе данных работает только один пользователь или группа скооперированных пользователей. Также данная стратегия позволяет смягчить переход из СУБД, где нет схем.

  • Вы можете создавать схему для каждого пользователя с именем, таким же как и у пользователя. Вспомните, что по умолчанию путь поиска начинается с элемента $user, который означает имя текущего пользоватля. Следовательно, если каждый пользователь имеет отдельную схему, то он по умолчанию получает доступ к своей схеме.

    Если вы используете такую стратегию, то вы можете также захотеть отобрать доступ к схеме public (или вообще удалить её), так что пользователи будут ограничены только своими схемами.

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

5.7.7. Переносимость

В стандарте SQL, не существует такого понятия, что у объектов в одной и той же схеме может быть разный владелец. Кроме того, некоторые реализации не разрешают создавать схемы, с именем отличным от имени их владельца. Фактически, концептуальные понятия схемы и пользователя, в тех СУБД, которые реализуют только базовую поддержку схем, обозначенную в стандарте, являются почти эквивалентыми. Следовательно, многие пользователи рассматривают полные имена, как реально состоящие из имя_пользователя.имя_таблицы. Это к вопросу, что PostgreSQL будет работать эффективно, если вы создадите пользовательскую схему для каждого пользователя.

Также, в стандарте SQL не существует концепции схемы public. Для максимального соответствия стандарту, вы не должны использовать (возможно даже удалить) схему public.

Разумеется, некоторые SQL СУБД могут вообще не иметь реализации схем или предоставлять поддержку пространств имён с помощью разрешения (возможно ограниченного) кросс-доступа между базами данных. Если вам необходимо работать с такими СУБД, то для достижения максимальной переностимости, вы не должны вообще использовать схемы.

Back to top

(С) Виктор Вислобоков, 2008-2023