Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции СУБД.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
6.32 Mб
Скачать

18.4.Проблемы, связанные со ссылочной целостностью

Существует четыре типа изменений базы данных, которые могут нарушить ссылочную целостность отношений предок/потомок. Рассмотрим каждую из этих четырех ситуаций на примере таблиц BRANCH и STAFF.

Добавление новой строки-потомка. Когда происходит добавление новой строки в таблицу – потомок (STAFF), значение ее внешнего ключа (BNO) должно быть равно одному из значений первичного ключа (BNO) в таблице-предке (BRANCH). Если значение внешнего ключа не равно ни одному из значений первичного ключа, то добавление такой строки разрушит базу данных, поскольку появится потомок без предка (“сирота”). Добавление строки в таблицу – предок не вызовет проблем; она просто станет предком без потомков.

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

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

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

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

Вторая проблема (обновление таблицы – потомка) решается аналогично: путем проверки нового значения внешнего ключа. Если нет ни одного равного ему значения первичного ключа, инструкция UPDATE отбрасывается с выдачей сообщения об ошибке.

Третья проблема (удаление строки-предка) является более сложной. Предположим, например, что вы закрыли отделение в Гродно и хотите удалить соответствующую строку из таблицы BRANCH. Как в этом случае поступить со строками – потомками таблицы STAFF? Очевидно, что в зависимости от ситуации можно:

не удалять из базы данных отделение до тех пор, пока служащие не будут переведены в другое отделение;

автоматически удалить всех соответствующих служащих из таблицы STAFF;

• в столбце STAFF.Bno установить значение NULL для всех соответствующих служащих, показывая тем самым, что идентификатор их офиса неизвестен;

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

Аналогичные сложности существуют и в четвертой ситуации (обновление первичного ключа в таблице – предке). Допустим, по каким-либо причинам требуется изменить идентификатор отделения в Витебске с 1 на 2. Подобно предыдущему примеру, возникает вопрос о том, как поступить со строками – потомками в таблице STAFF, представляющими служащих Витебского офиса. И снова проблему можно решить четырьмя способами:

не изменять идентификатор отделения до тех пор, пока служащие не будут переведены в другое отделение; в таком случае в таблицу BRANCH следует вначале добавить строку с новым идентификатором отделения в Витебске, затем обновить таблицу STAFF и, наконец, удалить строку со старым идентификатором Витебского отделения;

автоматически обновить идентификатор отделения этих служащих в таблице STAFF для того, чтобы их строки были по-прежнему связаны с Витебской строкой в таблице BRANCH через ее новый идентификатор;

• в столбце STAFF.Bno установить для соответствующих служащих значение NULL, показывая тем самым, что идентификатор их офиса неизвестен;

• в столбце STAFF.Bno установить по умолчанию для всех соответствующих служащих некоторое значение, например идентификатор главного офиса в Минске.

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

Эти правила были преобразованы в правила удаления и обновления, охватывающие как удаление строк – предков, так и обновление первичных ключей.