Ограничение ссылочной целостности

4. Ограничения ссылочной целостности

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

Как мы уже говорили раньше, внешний ключ объявляемого базового отношения ссылается на первичный или кандидатный ключ какого-то другого (чаще всего) базового отношения. Напомним, что при этом отношение, на которое ссылается внешний ключ, называется ссылочным или родительским, потому что оно как бы «порождает» один атрибут или несколько атрибутов в ссылающемся базовом отношении. А, в свою очередь, отношение, содержащее внешний ключ, называется дочерним, тоже по вполне понятным причинам.

В чем же заключается ограничение ссылочной целостности? А заключается оно в том, что каждому значению внешнего ключа дочернего отношения обязательно должно соответствовать значение какого-либо ключа отношения родительского, если только значение внешнего ключа не содержит Null-значений в каких-либо атрибутах.

Кортежи дочернего отношения, нарушающие это условие, называются висящими.

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

Но, зная, что ни одна база данных никогда не допустит создания висящего кортежа, разработчики следят за тем, чтобы изначально висящих кортежей в базе данных не было и все имеющиеся ключи ссылались на вполне реальный атрибут отношения родительского. Но тем не менее бывают ситуации, когда висящие кортежи образуются уже в процессе функционирования базы данных. Что это за ситуации? Известно, что при удалении кортежей из родительского отношения или при обновлении значения ключа кортежа родительского отношения ссылочная целостность может нарушиться, т. е. могут возникнуть висящие кортежи.

Для исключения возможности их появления при объявлении значения внешнего ключа задается одно из трех имеющихся правил поддержания ссылочной целостности, применяемых соответственно при обновлении значения ключа в родительском отношении (т. е., как мы уже упоминали раньше, on update) или при удалении кортежа из родительского отношения (on delete). Необходимо отметить, что добавление нового кортежа в родительское отношение не может нарушить ссылочную целостность по вполне понятным причинам. Ведь, если этот кортеж только что добавили в базовое отношение, раньше на него не мог ссылаться ни один атрибут по причине его отсутствия!

Итак, что же это за три правила, применяющиеся для поддержания в базах данных ссылочной целостности? Перечислим их.

1. Restrict, или правило ограничения. Если мы при задании нашего базового отношения, при объявлении внешних ключей в ограничении ссылочной целостности применили это правило ее поддержания, то обновление ключа в родительском отношении или удаление кортежа из родительского отношения просто не может быть выполнено в том случае, если на этот кортеж ссылается хотя бы один кортеж дочернего отношения, т. е. операция Restrict банально запрещает производить какие-либо действия, могущие привести к появлению висящих кортежей.

Проиллюстрируем применение этого правила следующим примером.

Пусть даны два отношения:

Родительское отношение

Дочернее отношение

Здесь только кортежи родительского отношения (…, 1) и (…, 4) допускают обновление значений ключа и удаление кортежей, потому что на них не ссылается ни один из внешних ключей дочернего отношения.

Составим оператор создания базового отношения, включающего в себя объявление всех вышеназванных ключей:

Create table Родительское отношение

not Null

primary key (Primary_key)

Create table Дочернее отношение

foreign key (Foreign_key) references Родительское отношение (Primary_key)

on update Restrict

on delete Restrict

2. Cascade, или правило каскадной модификации. Если при объявлении внешних ключей в нашем базовом отношении мы использовали правило поддержания ссылочной целостности Cascade, то обновление ключа в родительском отношении или удаление кортежа из родительского отношения вызывает автоматическое обновление или удаление соответствующих ключей и кортежей дочернего отношения.

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

Родительское отношение

и

Дочернее отношение

Допустим, мы в таблице, задающей отношение «Родительское отношение» обновим некоторые кортежи, а именно заменим кортеж (…, 2) на кортеж (…, 20), т. е. получим новое отношение:

Родительское отношение

И пусть при этом в операторе создания нашего базового отношения «Дочернее отношение» при объявлении внешних ключей мы использовали правило поддержания ссылочной целостности Cascade, т. е. оператор создания наших базовых отношений выглядит следующим образом:

Create table Родительское отношение

not Null

primary key (Primary_key)

Create table Дочернее отношение

foreign key (Foreign_key) references Родительское отношение (Primary_key)

on update Cascade

on delete Cascade

Тогда что же произойдет с отношением дочерним при обновлении родительского отношения указанным выше образом? Оно примет следующий вид:

Дочернее отношение

Таким образом, действительно, правило Cascade обеспечивает каскадное обновление всех кортежей дочернего отношения в ответ на обновления отношения родительского.

3. Set Null, или правило присвоения Null-значений. Если же мы в операторе создания нашего базового отношения при объявлении внешних ключей применяем правило поддержания ссылочной целостности Set Null, то обновление ключа родительского отношения или удаление кортежа из родительского отношения влечет за собой автоматическое присвоение Null-значений тем атрибутам внешнего ключа дочернего отношения, который Null-значения допускают. Следовательно, правило применимо, если такие атрибуты имеются.

Рассмотрим пример, который мы уже использовали ранее. Пусть нам даны два базовых отношения:

«Родительское отношение»

Дочернее отношение

Как можно заметить, атрибуты дочернего отношения допускают Null-значения, следовательно, правило Set Null в данном конкретном случае применимо.

Допустим теперь, что из родительского отношения был удален кортеж (…, 1), а кортеж (…, 2) обновлен, как и в предыдущем примере. Таким образом, родительское отношение принимает следующий вид:

Родительское отношение

Тогда с учетом того, что при объявлении внешних ключей дочернего отношения нами применялось правило поддержания ссылочной целостности Set Null, дочернее отношение примет следующий вид:

Дочернее отношение

На кортеж (…, 1) не ссылался ни один ключ дочернего отношения, поэтому его удаление не влечет за собой никаких последствий.

Сам оператор создания базового отношения с использованием правила Set Null при объявлении внешних ключей отношения выглядит следующим образом:

Create table Родительское отношение

not Null

primary key (Primary_key)

Create table Дочернее отношение

foreign key (Foreign_key) references Родительское отношение (Primary_key)

on update Set Null

on delete Set Null

Итак, мы видим, что наличие трех различных правил поддержания ссылочной целостности обеспечивают то, что во фразах on update и on delete функции могут быть разными.

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

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

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

Поделитесь на страничке

Следующая глава >

Запросы модификации данных

Введение в понятие «целостность данных»

Выполнение операторов модификации данных в таблицах базы данных INSERT, DELETE и UPDATE может привести к нарушению целостности данных и их корректности, т.е. к потере их достоверности и непротиворечивости.

Чтобы информация, хранящаяся в базе данных, была однозначной и непротиворечивой, в реляционной модели устанавливаются некоторые ограничительные условия – правила, определяющие возможные значения данных и обеспечивающие логическую основу для поддержания корректных значений. Ограничения целостности позволяют свести к минимуму ошибки, возникающие при обновлении и обработке данных.

В базе данных, построенной на реляционной модели, задается ряд правил целостности, которые, по сути, являются ограничениями для всех допустимых состояний базы данных и гарантируют корректность данных. Рассмотрим следующие типы ограничений целостности данных:

  • обязательные данные;
  • ограничения для доменов полей;
  • корпоративные ограничения;
  • целостность сущностей;
  • ссылочная целостность.

Обязательные данные

Некоторые поля всегда должны содержать одно из допустимых значений, другими словами, эти поля не могут иметь пустого значения.

Ограничения для доменов полей

Каждое поле имеет свой домен, представляющий собой набор его допустимых значений.

Корпоративные ограничения целостности

Существует понятие «корпоративные ограничения целостности » как дополнительные правила поддержки целостности данных, определяемые пользователями, принятые на предприятии или администраторами баз данных. Ограничения предприятия называются бизнес-правилами.

Целостность сущностей

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

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

Если допустить присутствие определителя NULL в любой части первичного ключа, это равносильно утверждению, что не все его поля необходимы для уникальной идентификации записей, и противоречит определению первичного ключа.

Ссылочная целостность

Указанное ограничение целостности касается внешних ключей. Внешний ключ – это поле (или множество полей) одной таблицы, являющееся ключом другой (или той же самой) таблицы. Внешние ключи используются для установления логических связей между таблицами. Связь устанавливается путем присвоения значений внешнего ключа одной таблицы значениям ключа другой.

Между двумя или более таблицами базы данных могут существовать отношения подчиненности, которые определяют, что для каждой записи главной таблицы (называемой еще родительской ) может существовать одна или несколько записей в подчиненной таблице (называемой также дочерней ).

Существует три разновидности связи между таблицами базы данных:

  • «один-ко-многим»;
  • «один-к-одному»;
  • «многие-ко-многим».

Отношение «один-ко-многим» имеет место, когда одной записи родительской таблицы может соответствовать несколько записей дочерней. Связь «один-ко-многим» иногда называют связью «многие-к-одному». И в том, и в другом случае сущность связи между таблицами остается неизменной.

Связь «один-ко-многим» наиболее распространена для реляционных баз данных. Она позволяет моделировать также иерархические структуры данных.

Отношение «один-к-одному» имеет место, когда одной записи в родительской таблице соответствует одна запись в дочерней. Это отношение встречается намного реже, чем отношение «один-ко-многим». Его используют, если не хотят, чтобы таблица БД «распухала» от второстепенной информации. Использование связи «один-к-одному» приводит к тому, что для чтения связанной информации в нескольких таблицах приходится производить несколько операций чтения вместо одной, когда данные хранятся в одной таблице.

Отношение «многие-ко-многим» имеет место в следующих случаях:

  • одной записи в родительской таблице соответствует более одной записи в дочерней таблице ;
  • одной записи в дочерней таблице соответствует более одной записи в родительской таблице.

Считается, что всякая связь «многие-ко-многим» может быть заменена на связь «один-ко-многим» (одну или несколько).

Часто связь между таблицами устанавливается по первичному ключу, т.е. значениям внешнего ключа одной таблицы присваиваются значения первичного ключа другой. Однако это не является обязательным – в общем случае связь может устанавливаться и с помощью вторичных ключей. Кроме того, при установлении связей между таблицами не требуется непременная уникальность ключа, обеспечивающего установление связи. Поля внешнего ключа не обязаны иметь те же имена, что и имена ключей, которым они соответствуют. Внешний ключ может ссылаться на свою собственную таблицу – в таком случае внешний ключ называется рекурсивным.

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

Существует несколько важных моментов, связанных с внешними ключами. Во-первых, следует проанализировать, допустимо ли использование во внешних ключах пустых значений. В общем случае, если участие дочерней таблицы в связи является обязательным, то рекомендуется запрещать применение пустых значений в соответствующем внешнем ключе. В то же время, если имеет место частичное участие дочерней таблицы в связи, то помещение пустых значений в поле внешнего ключа должно быть разрешено. Например, если в операции фиксации сделок некоторой торговой фирмы необходимо указать покупателя, то поле КодКлиента должно иметь атрибут NOT NULL. Если допускается продажа или покупка товара без указания клиента, то для поля КодКлиента можно указать атрибут NULL.

Следующая проблема связана с организацией поддержки ссылочной целостности при выполнении операций модификации данных в базе. Здесь возможны следующие ситуации:

  1. Вставка новой строки в дочернюю таблицу. Для обеспечения ссылочной целостности необходимо убедиться, что значение внешнего ключа новой строки дочерней таблицы равно пустому значению либо некоторому конкретному значению, присутствующему в поле первичного ключа одной из строк родительской таблицы.
  2. Удаление строки из дочерней таблицы. Никаких нарушений ссылочной целостности не происходит.
  3. Обновление внешнего ключа в строке дочерней таблицы. Этот случай подобен описанной выше первой ситуации. Для сохранения ссылочной целостности необходимо убедиться, что значение внешнего ключа в обновленной строке дочерней таблицы равно пустому значению либо некоторому конкретному значению, присутствующему в поле первичного ключа одной из строк родительской таблицы.
  4. Вставка строки в родительскую таблицу. Такая вставка не может вызвать нарушения ссылочной целостности. Добавленная строка просто становится родительским объектом, не имеющим дочерних объектов.
  5. Удаление строки из родительской таблицы. Ссылочная целостность окажется нарушенной, если в дочерней таблице будут существовать строки, ссылающиеся на удаленную строку родительской таблицы. В этом случае может использоваться одна из следующих стратегий:
    • NO ACTION. Удаление строки из родительской таблицы запрещается, если в дочерней таблице существует хотя бы одна ссылающаяся на нее строка.
    • CASCADE. При удалении строки из родительской таблицы автоматически удаляются все ссылающиеся на нее строки дочерней таблицы. Если любая из удаляемых строк дочерней таблицы выступает в качестве родительской стороны в какой-либо другой связи, то операция удаления применяется ко всем строкам дочерней таблицы этой связи и т.д. Другими словами, удаление строки родительской таблицы автоматически распространяется на любые дочерние таблицы.
    • SET NULL. При удалении строки из родительской таблицы во всех ссылающихся на нее строках дочернего отношения в поле внешнего ключа, соответствующего первичному ключу удаленной строки, записывается пустое значение. Следовательно, удаление строк из родительской таблицы вызовет занесение пустого значения в соответствующее поле дочерней таблицы. Эта стратегия может использоваться, только когда в поле внешнего ключа дочерней таблицы разрешается помещать пустые значения.
    • SET DEFAULT. При удалении строки из родительской таблицы в поле внешнего ключа всех ссылающихся на нее строк дочерней таблицы автоматически помещается значение, указанное для этого поля как значение по умолчанию. Таким образом, удаление строки из родительской таблицы вызывает помещение принимаемого по умолчанию значения в поле внешнего ключа всех строк дочерней таблицы, ссылающихся на удаленную строку. Эта стратегия применима лишь в тех случаях, когда полю внешнего ключа дочерней таблицы назначено некоторое значение, принимаемое по умолчанию.
    • NO CHECK. При удалении строки из родительской таблицы никаких действий по сохранению ссылочной целостности данных не предпринимается.
  6. Обновление первичного ключа в строке родительской таблицы. Если значение первичного ключа некоторой строки родительской таблицы будет обновлено, нарушение ссылочной целостности случится при том условии, что в дочернем отношении существуют строки, ссылающиеся на исходное значение первичного ключа. Для сохранения ссылочной целостности может применяться любая из описанных выше стратегий. При использовании стратегии CASCADE обновление значения первичного ключа в строке родительской таблицы будет отображено в любой строке дочерней таблицы, ссылающейся на данную строку.

Существует и другой вид целостности – смысловая (семантическая) целостность базы данных. Требование смысловой целостности определяет, что данные в базе данных должны изменяться таким образом, чтобы не нарушалась сложившаяся между ними смысловая связь.

Уровень поддержания целостности данных в разных системах существенно варьируется.

Идеология архитектуры клиент-сервер требует переноса максимально возможного числа правил целостности данных на сервер. К преимуществам такого подхода относятся:

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

К недостаткам хранения ограничений целостности на сервере можно отнести:

  • отсутствие у клиентского приложения возможности реагировать на некоторые ошибочные ситуации, возникающие на сервере при реализации тех или иных правил (например, ошибок при выполнении хранимых процедур на сервере);
  • ограниченность возможностей языка SQL и языка хранимых процедур и триггеров для реализации всех возникающих потребностей определения целостности данных.

На практике в клиентских приложениях реализуют лишь такие правила, которые тяжело или невозможно реализовать с применением средств сервера. Все остальные ограничения целостности данных переносятся на сервер.

Ограничения Oracle

Ограничения целостности в реляционных базах данных (и Oracle Database в частности) позволяют легко и автоматически применять важные бизнес-правила к таблицам базы данных. Например, в таблице, используемой в системе управления кадрами, нельзя завести сотрудника, не назначив ему руководителя. При создании связанных таблиц можно объявить необходимые ограничения целостности, которые должны быть удовлетворены при каждом вводе или модификации данных в таблице.

Для выполнения бизнес-правил можно также задействовать логику приложения,однако ограничения целостности обычно применять проще, и обычно они хорошо выполняют свою работу, гарантируя, что вставки, обновления и удаления данных таблиц будут соответствовать определенным правилам. С другой стороны, логика приложения обладает тем преимуществом, что позволяет отклонить или подтвердить данные без обращения к содержимому таблицы. Таким образом, выбирать метод выполнения бизнес-правил — логикой приложения или ограничениями целостности — необходимо на основе потребностей конкретного приложения. В любом случае ограничения целостности настолько фундаментальны для операций в реляционных базах данных, что вы обречены на их использование в конкретной базе.

По умолчанию Oracle разрешает значения null во всех столбцах. Если эти значения недопустимы для некоторых столбцов таблицы, для них необходимо задавать ограничение NOT NULL. Обратите внимание, что налагать ограничения базы данных на таблицы можно как во время их создания, так и позднее, с помощью команды ALTER TABLE.Однако очевидно, что если в таблице уже имеются значения null или дублированные данные, то изменить таблицу, применив ограничение NOT NULL или ограничение уникальности, будет невозможно.

Для таблицы Oracle можно установить несколько типов ограничений. Упрощенно их можно разделить на пять основных типов:

  • ограничения первичного ключа;
  • ограничения NOT NULL;
  • проверочные ограничения;
  • ограничения уникальности;
  • ссылочные ограничения целостности.

Все перечисленные типы ограничений обсуждаются далее в этой статье. В дополнение будет также представлен краткий обзор состояний ограничений целостности.

Ограничения первичного ключа

Первичный ключ — очень важный тип ограничения в таблице. Когда необходимо,чтобы значения столбца идентифицировались уникальным образом, это обеспечивается созданием первичного ключа по значению столбца. Столбец, на котором определен первичный ключ, должен быть уникальным и не null.

Таблица может иметь только один первичный ключ, который можно создать при создании таблицы, как показано в следующем примере:

SQL> CREATE TABLE dept (dept_id number(9) PRIMARY KEY);

Кроме того, можно добавить ограничение и к существующей таблице:

SQL> ALTER TABLE dept ADD PRIMARY KEY(dept_id);

Поскольку в предыдущем примере ограничению не присвоено имя, Oracle даст ему имя, сгенерированное системой. Если требуется присвоить ограничению собственное имя, воспользуйтесь следующей командой, которая назовет ограничение dept_pk:

SQL> ALTER TABLE dept ADD CONSTRAINT dept_pk PRIMARY KEY(dept_id); Table altered. SQL>

Обратите внимание, что если первичный ключ будет построен по более чем одному столбцу (т.е. будет составным), специфицировать назначение первичного ключа напротив имени столбца при создании таблицы нельзя. Столбцы первичного ключа должны быть указаны как отдельный элемент оператора CREATE TABLE после списка всех столбцов.

На заметку! В обоих предыдущих примерах Oracle автоматически создает индексы на столбце,который назначен первичным ключом.

Ограничения NOT NULL

Обычно таблица имеет один или более столбцов, в которых не допускается значение null — т.е. без значений. Хорошим примером является столбец last_name таблицы employee. Заставить пользователей обязательно вносить значения в этот столбец можно при создании таблицы, указав опцию NOT NULL для столбца, который не должен быть null:

SQL> CREATE TABLE employee (last_name VARCHAR(30) NOT NULL);

Если таблица уже создана, и требуется модифицировать столбец с допускающего null на не допускающий null, для этого можно использовать следующий оператор:

SQL> ALTER TABLE employee MODIFY last_name NOT NULL;

Проверочные ограничения

используете Проверочные (CHECK) ограничения применяются для обеспечения соответствия данных столбца определенным параметрам, которые вы укажете. Например,предположим, что годовая зарплата сотрудника фирмы не может быть равна или превышать $100 000 при определенных обстоятельствах. Это ограничение можно навязать с помощью следующего оператора, который устанавливает ограничение CHECK на столбце SALARY:

SQL> CREATE TABLE employee (employee_id NUMBER, last_name VARCHAR2(30), first_name VARCHAR2(30), department_id NUMBER, salary NUMBER CHECK(salary < 100000));

Ограничение уникальности

Ограничение уникальности (UNIQUE) очень распространено в реляционных базах данных. Эти ограничения гарантируют уникальность строк в реляционной таблице.В таблице могут существовать сразу несколько таких ограничений. Например, ограничение уникальности на столбце employee_id гарантирует, что ни один сотрудник не появится дважды в таблице employee.

В следующем примере первый оператор специфицирует ограничение уникальности на комбинации столбцов dept_name и location:

SQL> CREATE TABLE dept( dept_no NUMBER(3), dept_name VARCHAR2(15), location VARCHAR2(25), CONSTRAINT dept_name_ukey UNIQUE(dept_Name,location);

Создать уникальное ограничение на таблице department можно также с помощью такого оператора ALTER TABLE:

SQL> ALTER TABLE dept ADD CONSTRAINT dept_idx UNIQUE(dept_no); Table altered. SQL>

Ограничения ссылочной целостности

Ограничения ссылочной целостности гарантируют, что значения определенных важных столбцов будут иметь смысл. Предположим, что есть родительская таблица, которая ссылается на значения из другой таблицы, как в случае таблиц dept и employee.Сотрудник в таблице employee не может быть назначен в департамент, если такой департамент в таблице dept не существует.

Гарантировать существование действительного департамента можно с помощью ограничения ссылочной целостности. В этом случае столбец departament_id служит первичным ключом таблицы dept, а столбец dept_id в таблице employee, ссылающийся на соответствующий столбец таблицы department, называется внешним ключом. Таблица,содержащая внешний ключ, обычно называется дочерней таблицей, а таблица, содержащая ключ, на который ссылается внешний ключ — родительской таблицей. Как и со всеми прочими типами ограничений, ссылочные ограничения целостности можно создавать во время создания таблицы или позднее, с помощью оператора ALTER TABLE:

SQL> CREATE TABLE employee (employee_id NUMBER(7), last_name VARCHAR2(30), first name VARCHAR2(30), job VARCHAR2(15), dept_id NUMBER(3) NOT NULL CONSTRAINT dept_fkey REFERENCES dept(dept_id));

База данных назначает столбец dept_id таблицы employee внешним ключом, потому что он ссылается на столбец dept_id таблицы dept. Обратите внимание, что для того, чтобы столбец служил ссылочным (на который ссылаются), он должен быть уникальным или же быть первичным ключом в таблице, на которую установлена ссылка.

Состояния ограничений целостности

Как было показано в предыдущем выше, ограничения целостности определяются на таблицах для гарантии, что данные, нарушающие заранее установленные правила,в таблицу не попадут. Однако иногда, например, при загрузке данных, ограничения целостности не должны поддерживаться в действительном состоянии, поскольку это приведет к определенным проблемам. При необходимости Oracle позволяет отключать ограничения и затем включать их, когда они снова понадобятся. Давайте рассмотрим некоторые способы изменения состояния ограничений таблиц.

При загрузке больших объемов данных с использованием SQL*Loader или утилиты Import может потребоваться значительное время на загрузку данных, каждую строку которых нужно проверять на предмет нарушения целостности. Более эффективная стратегия предусматривает отключение ограничения, загрузку данных и последующую проверку корректности загруженных данных. После завершения загрузки ограничения вновь вводятся в действие посредством включения. Когда ограничение отключается,как описано здесь, база данных уничтожает индекс. Подобным образом реализуется лучшая стратегия — предварительное создание неуникальных индексов для ограничений, которые база данных не должна уничтожать, поскольку они обрабатывают дублированные записи.

На заметку! Состояние enabled (включено) — это состояние ограничений Oracle по умолчанию

Отключаются ограничения двумя способами: указание в качестве состояния ограничения либо disable validate (отключить с проверкой), либо disable no validate (отключить без проверки) с использованием конструкции DISABLE VALIDATE и DISABLE NO VALIDATE, соответственно. Аналогично, для включения ограничения применяются конструкции ENABLE VALIDATE и ENABLE NO VALIDATE. Ниже кратко обсуждаются различные способы включения и отключения ограничений.

Состояние Disable Validate

В случае использования команды DISABLE VALIDATE выполняются следующие два действия сразу. Во-первых, конструкция VALIDATE гарантирует, что все данные в таблице удовлетворяют условию ограничения. Во-вторых, конструкция DISABLE избавляет от необходимости поддерживать ограничение. Oracle сбрасывает индекс ограничения,но сохраняет его действительным. Вот пример:

SQL> ALTER TABLE sales_data ADD CONSTRAINT quantity_unique UNIQUE (prod_id,customer_id) DISABLE VALIDATE;

После выдачи приведенного выше оператора SQL наличие только уникальных комбинаций уникальных ключей prod_id и customer_id в таблице гарантируется, однако уникальный индекс не поддерживается.

Обратите внимание, что поскольку было решено сохранить ограничение в отключенном состоянии, никаких DML-действий в отношении таблицы выполнять нельзя. Эта опция идеально подходит для крупных таблиц хранилищ данных, которые обычно используются только для извлечения данных по запросам.

Состояние Disable No Validate

При отключении ограничения без проверки ограничение отключается, и нет никаких гарантий соответствия данных требованиям ограничения, поскольку Oracle не предпринимает проверку его действительности. Это по существу то же самое, что команда DISABLE CONSTRAINT.

Состояние Enable Validate

Это состояние ограничения включает ограничение, гарантируя проверку всех данных на соответствие условию ограничения. Это состояние в точности то же, что обычное состояние “включено”. Следующий пример демонстрирует использование этого состояния:

SQL> ALTER TABLE sales_data ADD CONSTRAINT sales_region_fk FOREIGN KEY (sales_region) REFERENCES region(region_id) ENABLE VALIDATE;

Состояние Enable No Validate

При этом состоянии ограничения база данных проверяет все новые вставки и обновления на соответствие условию ограничения. Поскольку существующие данные на такое соответствие не проверяются, нет уверенности, что они удовлетворяют этому условию ограничения. Обычно эта опция применяется при загрузке крупных таблиц,когда есть основания для уверенности, что эти таблицы уже удовлетворяют условию ограничения. Вот пример:

SQL> ALTER TABLE sales ADD CONSTRAINT sales_region_fk FOREIGN KEY (sales_region_id) REFERENCES time(time_id) ENABLE NOVALIDATE;

Более подходящая стратегия заключалась бы в использовании состояния DISABLE NOVALIDATE при загрузке данных, с переходом к состоянию ENABLE NOVALIDATE и затем к ENABLE VALIDATE в конце цикла извлечения, трансформации и загрузки (extraction,transformation, loading — ETL).

Ограничения Rely

Обычно перед загрузкой в таблицы хранилища данных предполагается выполнение шагов ETL. Если есть уверенность в качестве данных, можно сэкономить время на загрузку, отключив проверку ограничений. Для этого применяется команда ALTER TABLE с конструкцией RELY DISABLE NOVALIDATE, как показано в следующем примере:

SQL> ALTER TABLE sales ADD CONSTRAINT sales_region_fk FOREIGN KEY (sales_region_id) REFERENCES time(region_id) RELY DISABLE NOVALIDATE;

Отложенные и немедленные ограничения

В дополнение к указанию типа проверки достоверности ограничения можно специфицировать, когда именно должно проверяться ограничение в процессе загрузки данных.

Если хотите, чтобы ограничение проверялось немедленно после модификации данных, выберите опцию not defferable (не откладывая), которая, фактически задает поведение по умолчанию в базах данных Oracle. Если необходимо выполнить едино-временную проверку ограничения после фиксации всей транзакции, выберите опцию deferrable. Все ограничения и внешние ключи могут быть объявлены как deferrable или not deferrable.

В случае выбора опции deferrable появляются еще две дополнительных опции.Ограничение deferrable можно специфицировать либо как initially deferred, либо как initially immediate (изначально отложенное или изначально немедленное). В первом случае база данных откладывает проверки ограничения до окончания транзакции. Если же была выбрана опция initially immediate, то база данных проверит ограничения перед изменением любых данных. Обратите внимание, что если предварительно создается индекс, то он должен быть не уникальным, чтобы обработать дублированные значения.

Следующий пример показывает, как специфицировать такого рода ограничения в таблице employee:

SQL> CREATE TABLE employee employee_id NUMBER, last_name VARCHAR2(30), first_name VARCHAR2(30), dept VARCHAR2(30) UNIQUE REFERENCES department(dept_name) DEFERRABLE INITIALLY DEFERRED;

В Oracle также предусмотрен способ изменения отложенного ограничения с immediate на deferred или наоборот с помощью следующих операторов:

SQL> SET CONSTRAINT constraint_name DEFERRED; SQL> SET CONSTRAINT constraint_name IMMEDIATE;

Представления, относящиеся к ограничениям и индексам

Как определить, какие ограничения существуют на столбцах таблицы? Когда процесс завершается неудачей с сообщением о нарушении ссылочного ограничения целостности, как лучше всего определить, какого ограничения и какой таблицы это касается? Для решения подобных проблем необходимы представления словаря данных, относящиеся к ограничениям и индексам. Далее подробно рассматриваются ключевые ограничения такого рода.

DBA_CONSTRAINTS

Представление DBA_CONSTRAINTS предоставляет информацию обо всех типах ограничений таблицы в базе данных. Опрос этого представления делается, когда необходимо узнать, какого типа ограничения имеет таблица. Представление перечисляет несколько типов ограничений, как показано в следующем запросе:

SQL> SELECT DISTINCT constraint_type FROM DBA_CONSTRAINTS; Constraint_type ——————— C /* check constraints */ /* ограничения проверки */ P /* primary key constraint */ /* ограничение первичного ключа */ R /* referential integrity (foreign key) constraint */ /* ограничение ссылочной целостности (внешний ключ) */ U /* unique key constraint */ /* ограничение уникального ключа */ SQL>

Следующий запрос позволит узнать, какие ограничения установлены для таблицы TESTD. Ответ на запрос показывает, что таблица имеет единственное ограничение CHECK. Префикс SYS в столбце NAME отражает тот факт, что CONSTRAINT_NAME — имя по умолчанию, а не явно указанное владельцем таблицы.

SQL> SELECT constraint_name, constraint_type 2 FROM DBA_CONSTRAINTS 3* WHHERE table_name=’TESTD’; CONSTRAINT_NAME CONSTRAINT_TYPE ——————- ————— SYS_C005263 C SQL>

Обратите внимание, что если необходимо увидеть определенное ссылочное ограничение и правило удаления, то нужно применить следующую вариацию предыдущего запроса:

SQL> SELECT constraint_name, constraint_type, R_constraint_name, delete_rule FROM dba_constraints WHERE table_name=’ORDERS’; CONSTRAINT_NAME TYPE R_CONSTRAINT_NAME DELETE_RULE ———————- —— —————— ———— ORDER_DATE_NN C ORDER_CUSTOMER_ID_NN C ORDER_MODE_LOV C ORDER_TOTAL_MIN C ORDER_PK P ORDERS_SALES_REP_FK R EMP_EMP_ID_PK SET NULL ORDERS_CUSTOMER_ID_FK R CUSTOMERS_PK SET NULL 7 rows selected. SQL>

DBA_CONS_COLUMNS

Представление DBA_CONS_COLUMNS показывает имя столбца и позицию в таблице,где определено ограничение:

SQL> DESC DBA_CONS_COLUMNS Name —————- OWNER CONSTRAINT_NAME TABLE_NAME COLUMN_NAME POSITION SQL>

Вас заинтересует / Intresting for you:

Поддерживаемые Oracle типы дан… 2982 просмотров Валерий Павлюков Wed, 24 Oct 2018, 08:00:37Видеокурс по администрированию… 3850 просмотров Илья Дергунов Mon, 14 May 2018, 05:08:47Обновление до Oracle Database … 3724 просмотров Илья Дергунов Tue, 21 Nov 2017, 13:18:05Создание базы данных Oracle 9713 просмотров Александров Попков Wed, 14 Nov 2018, 12:44:39Author: Илья Дергунов Другие статьи автора:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *