Контроль ссылочной целостности
. Требование ссылочной целостности накладывает ограничения на все три операции обновления БД (см. табл. 2.1). Рассмотрим эти ограничения.
Операция
INSERT. Эта операция затрагивает только одно отношение. Если вставляется кортеж в отношение, не являющееся потомком ни в какой связи, то ссылочная целостность не может быть нарушена. Просто в БД появится новый кортеж, на который нет ссылок.
Если добавляется кортеж в отношение-потомок, то ссылочная целостность может быть нарушена. Кортеж можно включить в БД, если содержащееся в нем значение внешнего ключа принадлежит существующему в настоящий момент множеству значений родительского ключа. В РСУБД должна быть системная процедура проверки, подобная процедуре контроля целостности сущности. Она должна вызываться автоматически при любой попытке вставить кортеж в отношение-потомок. Входными данными для нее являются имя ссылочного отношения и значение набора атрибутов внешнего ключа. Процедура возвращает значение .F., если вводимое значение набора атрибутов внешнего ключа потомка не существует в текущем множестве значений первичного ключа родителя.
Процедура связывается с конкретным отношением в процессе обработки строки определения внешнего ключа в предложении определения отношения (см. п. 2.2.4.2). В соответствующий раздел системного каталога заносятся имя ссылочного отношения и перечень атрибутов, входящих в состав внешнего ключа потомка. Попытка выполнения операции INSERT всегда инициирует эту процедуру. Обновление отвергается, если процедура возвратила значение .F.
Операции DELETE и UPDATE. Удаление кортежа отношения, не являющегося ссылочным ни для какого другого, не может привести к нарушению ссылочной целостности. Так, в нашей БД «Поставщик-Деталь-Изделие» мы можем удалить без всяких последствий любой кортеж отношения SPJ.
Однако, если мы попытаемся удалить из отношения S какой-то кортеж, на который есть ссылка в SPJ, то это приведет к проблеме.
Пусть есть в S кортеж
‘S1’, ‘Иван’, 150, ‘Яя’,
а в
SPJ
– кортеж
‘S1’, ‘P3’, ‘J12’ 1000.
Удалив первый, мы нарушим требование ссылочной целостности, т.к. в SPJ
останется кортеж, содержащий значение ‘S1’, которого нет во множестве значений S.S#.
Аналогичная ситуация возникает при попытке обновить значение ссылочного ключа. Если понадобится изменить в S значение ‘S1’ на ‘S11’, то что делать с соответствующим значением SPJ. S#
?
Существует, по крайней мере, две возможности.
· Отложить удаление/обновление ссылочного ключа до тех пор, пока в БД не останется ни одного ссылающегося на него значения внешнего ключа. Кортеж из S, содержащий значение S.S# = ‘S1’, может быть удален только после того, как в SPJ
не останется ни одного кортежа, содержащего значение SPJ.S# = ‘S1’.
· Каскадировать удаление/обновление, т.е. удалить или обновить значение внешнего ключа во всех кортежах, ссылающихся на удаляемый/обновляемый родительский ключ. Например, удалить кортеж со значением S.S# = ‘S1’ и все кортежи SPJ со значением SPJ.S# = ‘S1’.
Таким образом, операции удаления/обновления родительского ключа затрагивают, по крайней мере, два
отношения – ссылочное и ссылающееся.
Для того чтобы система могла поддерживать ссылочную целостность при выполнении этих операций, нужно сообщить ей, что она должна делать с кортежами-потомками удаляемого кортежа-родителя, т.е. определить правило внешнего ключа.
Правило реализуется в виде хранимой процедуры – триггера ссылочной целостности. Триггер связывается в системном каталоге с внешним ключом потомка при обработке строки объявления внешнего ключа в предложении определения отношения (см. п. 2.4.2). Он запускается при любой попытке удаления/обновления значения родительского ключа.
Мы говорили о двух видах триггеров ссылочной целостности – ОТЛОЖИТЬ и КАСКАДИРОВАТЬ. Они наиболее часто используются на практике, поэтому РСУБД обычно имеют системные триггеры отложенного и каскадного удаления/обновления. Но возможные варианты действий не ограничиваются этими правилами.
Вообще говоря, правила внешнего ключа могут быть какими угодно.
Например, система может:
· предложить пользователю самостоятельно решить вопрос о том, что делать со ссылающимися кортежами;
· заменить значения внешнего ключа, ссылающиеся на удаляемое значение родительского, значениями по умолчанию;
· удалить ссылающиеся кортежи из отношения-потомка и занести их в некое архивное отношение и т.п.
Как правило, в БД, даже относительно простых, большинство отношений являются и ссылочными и ссылающимися. Правила внешних ключей устанавливаются для каждого из них индивидуально. При этом могут возникать сложные ситуации.
Например, пусть R1, R2, R3
– связанные отношения: R3 ® R2 ® R1. Для R2 определено каскадное удаление. Сделана попытка удаления кортежа R1, на который есть ссылки в R2. Следует удалить все кортежи R2, ссылающиеся на удаляемый кортеж R1. Однако на эти кортежи есть ссылки в R3. Если для R3 также установлено правило каскадного
удаления, то операция будет выполнена «лавиной». Если же для R3 определено отложенное удаление, то операция удаления из R2 не может быть выполнена, и, следовательно, не может быть выполнена операция удаления из R1.
Операции удаления/обновления всегда атомарны.
Либо выполняются все определенные правилами изменения в группе отношений, затронутых операцией, либо не выполняется ни одно, и состояние БД остается неизменным.