CREATE DOMAIN#
CREATE DOMAIN
CREATE DOMAIN — определить новый домен
Синтаксис
CREATE DOMAINname
[ AS ]data_type
[ COLLATEcollation
] [ DEFAULTexpression
] [constraint
[ ... ] ] whereconstraint
is: [ CONSTRAINTconstraint_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.