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