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
    • Задаёт значение по умолчанию для столбцов типа домена. Значение — любое выражение без переменных (подзапросы не допускаются). Тип данных выражения по умолчанию должен соответствовать типу данных домена. Если значение по умолчанию не указано, используется значение NULL.
    • Выражение по умолчанию будет использоваться при любой операции вставки, в которой не указано значение для столбца. Если для конкретного столбца задано значение по умолчанию, оно переопределяет любое значение по умолчанию, связанное с доменом. В свою очередь, значение по умолчанию домена переопределяет значение по умолчанию базового типа данных.
  • CONSTRAINT constraint_name
    • Необязательное имя ограничения. Если не указано, система генерирует имя автоматически.
  • NOT NULL
    • Запрещает значения NULL для этого домена (см. примечания ниже).
  • NULL
    • Разрешает значения NULL для этого домена. Это значение по умолчанию.
    • Этот параметр предусмотрен только для совместимости с нестандартными SQL-базами данных. Его использование не рекомендуется в новых приложениях.
  • CHECK (expression)
    • Предложения CHECK определяют ограничения целостности или условия, которым должны удовлетворять значения домена. Каждое ограничение должно быть выражением, возвращающим логическое значение. Оно должно использовать ключевое слово VALUE для ссылки на проверяемое значение. Выражения, возвращающие TRUE или UNKNOWN, проходят проверку. Если выражение возвращает FALSE, возникает ошибка, и значение не может быть преобразовано к типу домена.
    • В настоящее время выражения CHECK не могут содержать подзапросы и ссылаться на переменные, кроме VALUE.
    • Когда у домена есть несколько ограничений CHECK, они проверяются в алфавитном порядке по имени. (В версиях базы данных до 7.0 порядок срабатывания ограничений CHECK не гарантировался.)

Примечания

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

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

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

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

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

Пример распространённого нарушения этого предположения — ссылка на пользовательскую функцию в выражении CHECK и последующее изменение поведения этой функции. База данных не запрещает это, но она не заметит, если хранимые значения типа домена теперь нарушают ограничение 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