1. Ограничения
На поля таблицы могут быть наложены ограничения – специальные требования, или условия, которые ограничивают множество значений, которые могут быть присвоены полям таблицы. Эти условия обычно используются для того, чтобы запретить помещать в базу данных значения, которые являются логически неправильными или противоречивыми. Например, поле “Возраст”, объявленное как целочисленное, не может содержать отрицательные значения, или, например, значение менее 18, и т.д. В целом, ограничения отражают семантические свойства данных предметной области, и выявляются при ее анализе. Использовать ограничения не обязательно, более того, их определение в схеме базы данных потенциально снижает скорость работы системы, однако их использование эффективно предотвращает накапливание в БД неправильных данных и откровенного “мусора” и повышает качество и эксплуатационные свойства системы.
Проверка выполнения ограничения производится при выполнении SQL-сервером команд обновления данных (INSERT, UPDATE и DELETE), а так же при изменении структуры таблицы. Если ограничение при конкретном обновлении не выполняется, генерируется ошибка.
Объявление ограничения в команде CREATE TABLE может помещаться непосредственно после определения поля (эти ограничения так же называются ограничениями на уровне полей, или in-line-ограничениями), или отдельным описанием (в этом случае их называют ограничениями на уровне таблицы, или out-line-ограничениями). Для одного поля может быть определено несколько in-line-ограничений. Ограничение на уровне таблицы обычно используют для накладывания ограничения на несколько полей, а ограничение на уровне поля затрагивает, естественно, только одно это поле.
Полное определение ограничения имеет следующий синтаксис:
CONSTRAINT имя_ограничения описание_ограничения
Здесь имя_ограничения - имя, которое присваивается данному ограничению (должно быть уникальными среди всех использованных имен ограничений в данной схеме); явное присваивание имени ограничению полезно для дальнейших действий с этим ограничением. Для in-line-ограничений служебное слово CONSTRAINT и имя ограничения необязательны и могут быть пропущены, при этом имя для ограничения создается автоматически.
Ограничения в SQL Oracle бывают следующих видов:
Ограничение NOT NULL.
Ограничение первичного ключа PRIMARY KEY.
Ограничение доменной целостности CHECK.
Ограничение уникальности UNIQUE.
Ограничение референциальной целостности FOREIGN KEY.
Если на поле наложено ограничение NOT NULL, это означает, что в данном поле любой записи не может храниться значение NULL. Данное ограничение – единственное, которое может быть наложено на поля “длинных” типов BLOB и CLOB.
Это ограничение полезно, если в поле планируется хранить информацию, которая является обязательной и не может быть опущена или вставлена позднее.
Ограничение уникальности UNIQUE используется для того, чтобы в данном поле значения во всех записях были различными, или, иными словами, в таблице не должно существовать две записи с одинаковыми значениями этого поля. Это ограничение может быть наложено на одно поле или на группу полей; однако нельзя на одни и те же поля накладывать ограничение UNIQUE дважды.
Следует иметь в виду, что, если на группу полей наложено ограничение уникальности, из этого не следует, что каждой поле из набора само так же является уникальным. Например, если на пару полей “Имя” и “Фамилия” наложено это ограничение, конечно, сами по себе имена и фамилии, которые можно хранить в записях, могут повторяться. Кроме того, могут встречаться и пустые значения.
Частными случаем ограничения уникальности является ограничение первичного ключа PRIMARY KEY, которое требует дополнительно отсутствие пустых значений в группе полей. В дополнении к этому, ограничение PRIMARY KEY может встречаться только один раз среди ограничений на таблицу; впрочем, эквивалентная комбинация NOT NULL UNIQUE может быть наложена на любые другие поля.
Термин “первичный ключ” восходит к терминологии теории реляционных баз данных, согласно которой было принято разделять все возможные ключи на первичный и прочие, называемые вторичными, альтернативными и т.д. По существу, ключ таблицы – это группа полей с наложенным на них ограничением уникальности.
Ограничение доменной целостности (CHECK) позволяет контролировать присваиваемое значение данному полю при помощи логического выражения, которое проверяется при присваивании значения и, в случае если значение равно FALSE, ограничение считается нарушенным и возбуждается ошибка. В этом выражении можно использовать различные операции, содержащие присваиваемое значение поля и значения других полей данной записи, если ограничение объявлено как out-of-line. Подзапросы, однако, использовать нельзя, что означает, что при проверке нельзя анализировать данные из других строк этой же таблицы или других таблиц.
Наконец, последним из рассматриваемых ограничений является ограничение внешнего ключа, или ограничение референциальной целостности. Данное ограничение требует, чтобы в качестве значений поля или группы полей можно было использовать только значения полей какой-либо таблицы. Таблицу, на которую ссылается ограничение, называют часто master-таблицей, или родительской, а таблицу, в которой это ограничение определено – slave-таблицей, или подчиненной. Описание ограничений FOREIGN KEY, соответственно, содержит имя родительской таблицы и список ее полей, причем в родительской таблице на эту группу полей должно существовать наложенное ограничение UNIQUE или PRIMARY KEY.
Наконец, пре определении ограничения референциальной целостности можно определить поведение системы при удалении или изменении полей, на которые ссылается вешний ключ. Действительно, что должно происходить, если удалить запись в master-таблице, на которую ссылаются записи в подчиненной таблице? Данный вопрос регламентируется следующим образом. По умолчанию изменения полей референциального ключа и удаление содержащей его записи запрещено; однако существует две дополнительных опции – SET NULL для принудительного присваивания полям внешнего ключа значений NULL при удалении “родительской” записи, и опция CASCADE для удаления “подчиненных” записей. Перенос изменений от “родительских” записей к “подчиненным” называется каскадным обновлением.
