Аномалии модификации
Раздел: Проектирование баз данныхРассмотрим опять отношение СЕКЦИЯ. Если мы удалим строку, где записаны данные о студенте с номером 100, мы потеряем не только информацию о том, что студент с номером 100 является лыжником, но и тот факт, что абонемент в секцию лыж стоит $200. Это называется аномалией удаления (deletion anomaly) — то есть, удаляя факты, относящиеся к одной сущности (студент с номером 100 является лыжником), мы непроизвольно удаляем факты, относящиеся к другой сущности (плата за абонемент в секцию лыж составляет $200). Выполнив одну операцию удаления, мы теряем информацию о двух сущностях.
На примере того же самого отношения можно продемонстрировать аномалию вставки (insertion anomaly). Предположим, мы хотим записать в базу данных тот факт, что абонемент в секцию подводного плавания стоит $175, однако мы не можем ввести эти данные в отношение СЕКЦИЯ, пока хотя бы один студент не запишется в секцию подводного плавания. Это ограничение выглядит глупо.
Почему для того, чтобы указать стоимость абонемента, требуется ждать, когда кто-нибудь запишется в секцию? Это ограничение называется аномалией вставки. Суть его в том, что мы не можем записать в таблицу некоторый факт об одной сущности, не указав дополнительно некоторый факт о другой сущности.
Теперь, если мы удалим запись о студенте с номером 100 из таблицы СТУДЕНТ-СЕКЦИЯ, мы уже не потеряем тот факт, что абонемент в секцию лыж стоит $200. Более того, мы можем добавить в таблицу СЕКЦИЯ-ПЛАТА секцию подводного плавания с указанием стоимости абонемента, не дожидаясь, пока кто-либо запишется в эту секцию. Таким образом, аномалии удаления и вставки устранены.
Разбиение одного отношения на два имеет, однако, один недостаток. Предположим, что студент хочет записаться в несуществующую секцию. Например, студент с номером 250 хочет записаться в секцию ракетбола. Мы можем вставить соответствующую строку в отношение СТУДЕНТ-СЕКЦИЯ (строка будет содержать запись (250, Ракетбол)), но следует ли это делать? Стоит ли разрешать студенту записываться в секцию, которая отсутствует в отношении СЕКЦИЯ-ПЛАТА? Другими словами, должна ли система каким-либо образом препятствовать добавлению строк в таблицу СТУДЕНТ-СЕКЦИЯ, если название соответствующей секции отсутствует в таблице СЕКЦИЯ-ПЛАТА? Ответ на этот вопрос содержится в требованиях пользователей. Если такое действие должно быть запрещено, данное ограничение (а это не что иное, как статья делового регламента) необходимо внести в схему базы данных. Позже, на стадии реализации, выполнение этого ограничения будет возложено иа СУБД, если используемая СУБД предоставляет такую возможность. Если нет, то соблюдение ограничения должно обеспечиваться прикладными программами.
Допустим, пользователи указывают, что секции могут существовать и до того, как кто-либо в них запишется, однако студент не может записаться в секцию, для которой не указан размер платы за абонемент (то есть в секцию, данные о которой отсутствуют в таблице СЕКЦИЯ-ПЛАТА). При проектировании базы данных мы можем задокументировать это ограничение любым из следующих способов: «множество значений атрибута Секция в таблице СТУДЕНТ-СЕКЦИЯ является подмножеством множества значений атрибута Секция в таблице СЕКЦИЯ-ПЛАТА», «СТУДЕНТ-СЕКЦИЯ [Секция] является подмножеством СЕКЦИЯ-ПЛАТА [Секция]» либо «СТУДЕНТ-СЕКЦИЯ [Секция] с СЕКЦИЯ-ПЛАТА [Секция]».
Квадратные скобки в этой записи обозначают столбец данных, извлекаемый иэ отношения. Смысл этих выражений в том, что атрибут Секция в отношении СТУДЕНТ-СЕКЦИЯ может принимать только те значения, которые имеет атрибут Секция в отношении СЕКЦИЯ-ПЛАТА. Это означает также, что прежде чем ввести название какой-то секции в отношение СТУДЕНТ-СЕКЦИЯ, мы должны проверить, что такое название уже существует в отношении СЕКЦИЯ-ПЛАТА. Ограничения, подобные этому, называются ограничениями ссылочной целостности (referential integrity constraints), или ограничениями целостности по внешнему ключу (interrelation constraints).