CREATE DOMAIN
Эта страница переведена при помощи нейросети GigaChat.
CREATE DOMAIN
— создание нового домена.
Синтаксис
CREATE DOMAIN name [ AS ] data_type
[ COLLATE collation ]
[ DEFAULT expression ]
[ domain_constraint [ ... ] ]
Где domain_constraint:
[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }
Описание
CREATE DOMAIN
используется для создания нового домена. Домен представляет собой пользовательский тип данных с возможными дополнительными ограничениями на допустимые значения. Пользователь, создавший домен, автоматически становится его владельцем.
Если указано имя схемы (например, CREATE DOMAIN myschema.mydomain ...
), домен будет создан в указанной схеме. В противном случае он создается в текущей активной схеме. Имя домена должно быть уникальным в пределах типов и доменов в данной схеме.
Домены позволяют централизованно управлять общими ограничениями, характерными для различных таблиц. Например, если в нескольких таблицах используются поля для email-адресов с одинаковыми правилами валидации, можно создать домен с нужным ограничением проверки для проверки синтаксиса адреса, вместо того чтобы дублировать это ограничение в каждой таблице.
Для создания домена необходимо обладать привилегией USAGE
на базовый тип данных.
Параметры
name
- Задает имя домена, при необходимости дополненное схемой, который должен быть создан.
data_type
- Задает тип данных, лежащий в основе домена. Разрешены также формы с массивами.
collation
- Необязательное указание сортировки. Если
COLLATE
не задан, домен наследует поведение сортировки от своего типа данных, лежащего в основе. Основной тип должен поддерживать сортировку, если указана сортировка.
DEFAULT expression
- Определяет значение по умолчанию для столбцов, типом данных которых является этот домен. Указывается любое выражение без переменных (подзапросы запрещены). Тип данных этого выражения должен соответствовать типу данных домена. Если значение по умолчанию не задано, используется
NULL
.Значение по умолчанию применяется в любой операции добавления строк, в которой не задано значение для этого столбца. Если значение по умолчанию установлено для конкретного столбца, оно будет переопределять значение по умолчанию, связанное с доменом. В свою очередь, значение по умолчанию для домена переопределяет любое значение по умолчанию, связанное с нижележащим типом данных.
CONSTRAINT constraint_name
- Задает имя ограничения. Если не задано, система создаст его автоматически.
NOT NULL
- Запрещает использование
NULL
в значениях этого домена. Подробнее описано в примечаниях ниже.
NULL
- Разрешает использование
NULL
. Это значение используется по умолчанию.Данный параметр предусмотрен для совместимости с нестандартными реализациями SQL и не рекомендуется к использованию в новых приложениях.
CHECK (expression)
- Добавляет ограничение, проверяющее логическое выражение. Оно должно ссылаться на значение, подлежащее проверке (как правило, через ключевое слово
VALUE
). Если результат выражения —TRUE
илиUNKNOWN
, значение считается допустимым. Если результат —FALSE
, операция завершается ошибкой.Выражение не может содержать подзапросы или переменные, кроме
VALUE
.Если указано несколько ограничений, они выполняются в алфавитном порядке по именам. В версиях PostgreSQL до 9.5 не было никакого определенного порядка обработки ограничений
CHECK
.
Примечания
Ограничения домена, в частности CHECK
и NOT NULL
, проверяются при приведении значения к типу домена. Однако в некоторых случаях может показаться, что такие ограничения игнорируются — например, при использовании внешнего соединения, если столбец доменного типа находится на внешней стороне и принимает NULL
. Другой пример:
INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));
Здесь подзапрос возвращает NULL
, что допускается как значение доменного типа, и проверка ограничений не выполняется.
Это связано с тем, что в SQL по умолчанию NULL
допустим для всех типов. Поэтому лучшей практикой является разрешение NULL
в домене и явное добавление NOT NULL
в конкретных столбцах таблиц.
PostgreSQL предполагает, что выражения CHECK
являются детерминированными — то есть возвращают одинаковый результат для одного и того же входа. Вследствие этого такие проверки выполняются только при первом приведении значения к типу домена, а не каждый раз при доступе. Это аналогично тому, как работают CHECK
ограничения таблиц.
Нарушение этого предположения возможно, если выражение CHECK
использует пользовательскую функцию, а затем ее поведение изменяется. PostgreSQL не отслеживает, какие сохраненные значения перестали удовлетворять ограничению 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.
Синтаксис NOT NULL
в этой команде является расширением PostgreSQL. Стандартный способ записи того же самого для данных немассивных типов был бы CHECK (VALUE IS NOT NULL
). Однако согласно разделу под названием «Примечания», таких ограничений лучше избегать на практике. Ограничение NULL
является расширением PostgreSQL.