CREATE DOMAIN#

CREATE DOMAIN

CREATE DOMAIN

CREATE DOMAIN — определить новый домен

Синтаксис

CREATE DOMAIN name [ AS ] data_type
    [ COLLATE collation ]
    [ DEFAULT expression ]
    [ constraint [ ... ] ]

where constraint is:

[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }

Описание

Создание домена CREATE DOMAIN создает новый домен. Домен представляет собой, по сути, тип данных с опциональными ограничениями (ограничениями на допустимый набор значений). Пользователь, который определяет домен, становится его владельцем.

Если указано имя схемы (например, CREATE DOMAIN myschema.mydomain ...), то домен создается в указанной схеме. В противном случае он создается в текущей схеме. Имя домена должно быть уникальным среди типов и доменов, существующих в его схеме.

Домены полезны для абстрагирования общих ограничений на поля в одном месте для обслуживания. Например, несколько таблиц могут содержать столбцы с адресами электронной почты, все требующие одного и того же ограничения CHECK для проверки синтаксиса адреса. Определите домен вместо установки ограничения для каждой таблицы отдельно.

Чтобы создать домен, необходимо иметь привилегию USAGE на базовый тип.

Параметры

name

Имя (опционально с указанием схемы) создаваемого домена.

data_type

Тип данных, на котором основан домен. Это может включать спецификаторы массива.

collation

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

DEFAULT expression

Предложение DEFAULT указывает значение по умолчанию для столбцов типа данных домена. Значение может быть любым выражением без переменных (но подзапросы не допускаются). Тип данных выражения по умолчанию должен соответствовать типу данных домена. Если значение по умолчанию не указано, то оно будет равно значению null.

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

CONSTRAINT constraint_name

Необязательное имя для ограничения. Если не указано, система генерирует имя.

NOT NULL

Значения этого домена не могут быть пустыми (см. примечания ниже).

NULL

Значения этого домена могут быть равны null. Это значение по умолчанию.

Эта предложение предназначена только для обеспечения совместимости с нестандартными SQL-базами данных. Рекомендуется избегать ее использования в новых приложениях.

CHECK (expression)

Предложения CHECK определяют ограничения целостности или тесты, которым должны удовлетворять значения домена. Каждое ограничение должно быть выражением, возвращающим логический результат. Оно должно использовать ключевое слово VALUE для ссылки на тестируемое значение. Выражения, вычисляющиеся в TRUE или UNKNOWN, успешны. Если выражение дает ложный результат, сообщается об ошибке, и значение не может быть преобразовано в тип домена.

В настоящее время выражения CHECK не могут содержать подзапросы или ссылаться на переменные, отличные от VALUE.

Когда у домена есть несколько ограничений CHECK, они будут проверяться в алфавитном порядке по имени. (В версиях PostgreSQL до 9.5 не соблюдался никакой определенный порядок выполнения ограничений CHECK.)

Примечания

Ограничения домена, особенно NOT NULL, проверяются при преобразовании значения в тип домена. Возможно, что столбец, который формально имеет тип домена, может быть прочитан как null, несмотря на наличие такого ограничения. Например, это может произойти в запросе с внешним соединением, если столбец домена находится на стороне, допускающей null. Более тонкий пример:

INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));

Пустой скалярный подзапрос произведет значение null, которое считается доменным типом, поэтому к нему не применяется дополнительная проверка ограничений, и вставка будет успешной.

Избежать таких проблем очень сложно из-за общего предположения SQL о том, что значение null является допустимым значением для каждого типа данных. Поэтому лучшей практикой является проектирование ограничений домена таким образом, чтобы значение null было допустимо, а затем применять ограничения NOT NULL к столбцам типа домена по мере необходимости, а не напрямую к типу домена.

Tantor SE предполагает, что условия ограничений CHECK являются неизменными, то есть они всегда будут давать одинаковый результат для одного и того же входного значения. Это предположение обосновывает проверку ограничений CHECK только при первом преобразовании значения к типу домена, а не в другие моменты времени. (Это в основном аналогично обработке ограничений CHECK таблицы, как описано в разделе Раздел 5.4.1).

Пример обычного способа нарушения этого предположения - ссылка на пользовательскую функцию в выражении CHECK, а затем изменение поведения этой функции. Tantor SE не запрещает это, но он не заметит, если есть сохраненные значения типа домена, которые теперь нарушают ограничение CHECK. Это может вызвать сбой последующего создания резервной копии и восстановления базы данных. Рекомендуется обрабатывать такое изменение путем удаления ограничения (с помощью ALTER DOMAIN), изменения определения функции и повторного добавления ограничения, тем самым повторной проверки его на сохраненные данные.

Примеры

Этот пример создает тип данных us_postal_code и затем использует этот тип в определении таблицы. Для проверки того, что значение выглядит как действительный почтовый индекс США, используется регулярное выражение:

CREATE DOMAIN us_postal_code AS TEXT
CHECK(
   VALUE ~ '^\d{5}$'
OR VALUE ~ '^\d{5}-\d{4}$'
);

CREATE TABLE us_snail_addy (
  address_id SERIAL PRIMARY KEY,
  street1 TEXT NOT NULL,
  street2 TEXT,
  street3 TEXT,
  city TEXT NOT NULL,
  postal us_postal_code NOT NULL
);

Совместимость

Команда CREATE DOMAIN соответствует стандарту SQL.

См. также

ALTER DOMAIN, DROP DOMAIN