Наиболее весомым аргументом
в пользу выбора суррогатных ключей часто
называют проблему неустойчивости интеллектуальных
ключей и, соответственно, большей устойчивости
суррогатных ключей.
Интеллектуальный ключ жёстко
привязан к предметной области, и все флуктуации
предметной области могут задевать значения,
хранимые в интеллектуальном первичном
ключе. И это действительно так. Здесь
возможны две ситуации. Первая состоит
в том, что одно значение, хранимое в интеллектуальном
ключе, замещается другим значением. В
такой ситуации, возможно, потребуется
выполнить каскадные (CASCADE) обновления
или заменить значения во внешних ключах
на значение, назначенное по умолчанию
(DEFAULT), пустое (NULL) значение или
вообще запретить обновление (NO ACTION).
Все эти ситуации описаны и закреплены
в стандарте SQL 92. Так при объявлении
внешнего ключа можно указать требуемые
реакции на две основные операции: обновление
и удаление. В следующем примере поле FLD2
ссылается на поле FLD1 той же таблицы,
то есть является внешним ключом:
CREATE TABLE EXAMPLE_TABLE1(
FLD1 CHAR(10) NOT NULL PRIMARY KEY,
FLD2 CHAR(10) REFERENCES EXAMPLE_TABLE1 (FLD1)
...);
При удалении кортежа,
все ссылающиеся на него другие кортежи,
будут теперь вместо ссылки иметь значение
NULL, но при обновлении атрибута FLD1
все, ссылающиеся на данный кортеж, другие
кортежи также примут новое значение. СУБД,
поддерживающие требование стандарта, полностью
снимают с разработчика базы данных проблему
поддержания ссылочной целостности при
операциях обновления первичных ключей
и удаления кортежей. Безусловно, операции,
сопровождающиеся каскадными изменениями,
будут выполняться дольше операций, не
требующих каскадных изменений. Применение
суррогатных ключей позволяет избежать
каскадных изменений (UPDATE). Действительно
в данном случае изменяется атрибут, не
входящий в первичный ключ, а, следовательно,
в ссылочных отношениях делать изменения
не потребуется. Против каскадных удалений
суррогатные ключи бессильны. Удаление
кортежа в одном отношении потребует всех
связанных кортежей того же и/или других
отношений.
С другой стороны, изменения
значений ключевых полей требуется не так
часто. В примере с паспортными данными,
который рассматривался в начале статьи
показано, что получение нового паспорта
не обязательно сопряжено с изменением
значений ключевых полей. Новый паспорт
реально ссылается на того же человека,
что и старый паспорт. Мало того, возможны
ситуации, когда человек имеет одновременно
оба паспорта, например, считалось, что
старый паспорт потерян, но он был найден
спустя некоторое время после того, как
уже был выдан новый паспорт. Если бы атрибуты
серии и номера паспорта были включены
в сущность «Служащие» и по ним бы проводилась
идентификация служащего, то проблему двух
паспортов решить было бы не так просто.
Но разумное разделение сущностей «Служащие»
и «Документы» исключает потребность в
каскадных обновлениях.
Другим примером аналогичной
ситуации может служить изменение названий,
выбранных в качестве первичного ключа.
Предположим, что в базе данных существует
таблица «Фирмы-разработчики», которая
имеет в качестве первичного ключа атрибут
«Краткое название». Пусть в этой таблице
один из кортежей имел ключ со значением
«AT&T», но через какое-то время данная
фирма была переименована в «Lucent». На
первый взгляд нам потребуется сделать
изменения не только в первичном ключе
данной таблицы, но провести каскадные
изменения внешних ключей, имеющих в своём
составе данное поле. Под такие изменения,
частности попадает и таблица «Позиции
заказа», которая связывает заказ с моделями
микросхем различных фирм-разработчиков.
Однако такое изменение недопустимо, вследствие
того, что изменится содержание отчётных
документов, таких как, оплаченные заказы.
Какой выход можно предложить в данной
ситуации? Надо добавить новое поле к таблице
«Фирмы-разработчики», и это поле должно
ссылаться на эту же таблицу по её первичному
ключу. Назовём это поле «Старое название».
Теперь можно внести новый кортеж, где
в качестве названия указать фирму «Lucent»,
и в поле «Старое название» записать значение
«AT&T». Это решение не только не потребует
каскадных изменений внешних ключей, но
и сохранит отчётные документы в первозданном
виде.
Применение суррогатного
ключа в подобной ситуации не спасло бы
положения, поскольку изменение значения
в поле «Краткое название» таблицы «Фирмы-разработчики»
привело бы к тому, что автоматически изменились
бы и отчётные документы.
Безусловно, изменение значений
первичного ключа, связанное с ошибками
ввода потребует проведения каскадных изменений
во внешних ключах. Но это едва ли не единственный
случай, когда подобные изменения действительно
необходимы и оправданы. Но, с другой стороны,
это хороший стимул для того, чтобы продумать
систему мер от таких ошибок, в частности,
автоматизировать ввод важнейшей информации,
входящей в интеллектуальные ключи. В конце
концов, суррогатные ключи тоже не защищают
от ошибок ввода, они просто делают исправления
менее болезненными.
Вторая ситуация, связанная
с изменениями интеллектуального ключа,
состоит в том, что меняется тип атрибута,
входящего в ключ. Например, возможна ситуация,
когда вместо целого атрибута потребовалось
использовать строковый атрибут, или размера
атрибута оказалось недостаточно для сохранения
значения и атрибут требуется увеличить.
Такие ситуации возможны и они требуют
гораздо более сложных операций, чем простое
каскадное изменение значений во внешних
ключах. Прежде всего, потребуется изменить
структуру внешних ключей, которые ссылаются
на первичный ключ, в котором произошли
изменения. Операция по изменению нескольких
отношений, в свою очередь, требует сохранения
и переформатирования хранимой информации.
Таким образом, изменение
структуры первичного ключа превращается
в сложную операцию по модификации части
базы данных. Применение суррогатных ключей
в данной ситуации позволяет значительно
упростить решение задачи, поскольку потребуется
изменить поля только одного отношения,
не задевая внешних ключей других отношений.
Возникает резонный вопрос о том, можно
ли решение об использовании суррогатных
ключей считать наилучшим из всех возможных
решений. Но для ответа на данный вопрос
необходимо сначала разобраться в том,
является ли данное решение адекватным
проблеме. Проблема изменения структуры
первичного ключа может быть вызвана двумя
факторами. Первый фактор – ошибка проектирования.
Второй фактор – реальные изменения, происходящие
в предметной области.
|