Быстрый старт
Развертывание
Моделирование данных
Подключение
Запись данных
Миграция
Запросы
Операции и обслуживание
Типовое обслуживание
Секционирование
Резервное копирование и восстановление
Масштабирование
Зеркалирование
Управление ресурсами
Безопасность
Мониторинг
Настройка производительности
Устранение неполадок
Справочник
Руководство по инструментам
Типы данных
Хранилище данных
Выполняющая система
Потоковая передача
Восстановление после сбоев
Конфигурация
Индексы
Расширения
Справочник по SQL
Часто задаваемые вопросы
Определяет новый домен.
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 на базовый тип данных.
Ограничения домена, особенно 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.