
Связанные отношения
Ещё одним важным понятием реляционной модели является связь (relationship) между отношени-ями. В реляционной модели данные представляются в виде совокупности логически связанных отно-шений (таблиц).
Для рассмотрения связанных отношений воспользуемся рассмотренным ранее примером — отношением СТУДЕНТЫ. Данное отношение может быть связано с другим отношением — УСПЕВАЕМОСТЬ, в котором содержатся сведения об успеваемости студентов по разным предметам. Фрагмент такого отношения может иметь вид, приведенный в табл. 4.
Таблица 4. Фрагмент отношения УСПЕВАЕМОСТЬ, связанного с отношением СТУДЕНТЫ
Атрибут «№_студенческого_билета» таблицы УСПЕВАЕМОСТЬ содержит идентификатор сту-дента (в данном примере в качестве такого идентификатора используется номер студенческого билета). Причём, значения в столбце «№_студенческого_билета» таблицы УСПЕВАЕМОСТЬ могут повторяться (условие уникальности значений для этого столбца не установлено). Если нужно узнать имя студента, имеющего номер студенческого билета 22991380, получившего по высшей математике 3 и ещё не сдававшего философию, то следует поискать номер студенческого билета 22991380 в поле «№_студенческого_билета» таблицы СТУДЕНТЫ (см. таблицу СТУДЕНТЫ) и в найденной строке прочесть значение поля «Имя». Заметим, что в данном случае однозначно идентифицировать студента по имени можно только потому, что для столбца «№_студенческого_билета» таблицы СТУДЕНТЫ выполняется условие уникальности. Таким образом, связь между таблицами СТУДЕНТЫ и УСПЕВАЕМОСТЬ устанавливается по атрибуту «№_студенческого_билета».
При рассмотрении связанных таблиц важное значение имеет понятие внешнего ключа. Рассмотрим его более подробно.
Внешние ключи отношения
В базах данных одни и те же имена атрибутов часто используются в разных отношениях. В рассмат-риваемом примере атрибут «№_студенческого_билета» присутствует как в отношении СТУДЕНТЫ, так и в отношении УСПЕВАЕМОСТЬ. В этом примере атрибут «№_студенческого_билета» отношения УСПЕВАЕМОСТЬ иллюстрирует понятие внешнего ключа (foreign key).
Внешний ключ — это атрибут (или совокупность атрибутов) одного отношения, связанный с первичным ключом другого (или того же самого) отношения. Реляционная модель требует, чтобы внешние ключи таблицы были связаны именно с первичными ключами других таблиц данной БД, а не просто с потенциальными ключами. (На практике это требование, достаточно часто, не соблю-дается, то есть разрешается связывание внешнего ключа одной таблицы с потенциальным ключом другой таблицы.)
Внешние ключи используются для установления логических связей между отношениями. Связь между двумя таблицами устанавливается путем присваивания значений первичного ключа одной таблицы значениям внешнего ключа другой таблицы.
Так же как и любые другие ключи, внешние ключи могут быть простыми либо составными.
Как уже говорилось ранее, обычно связь между отношениями устанавливается по первичному ключу, то есть значениям внешнего ключа одного отношения присваиваются значения первичного ключа другого отношения. Однако это не является обязательным — в общем случае связь может уста-навливаться также и с помощью потенциальных ключей. Более того, в некоторых СУБД допускается установление связей по вторичным ключам. В этом случае необязательным является требование уни-кальности ключа, по которому устанавливается связь.
Атрибуты внешнего ключа таблицы не обязательно должны иметь те же имена, что и атрибуты первичного ключа таблицы, с которой связана таблица, имеющая внешний ключ. Например, в нашем примере можно было дать атрибуту «№_студенческого_билета» таблицы УСПЕВАЕМОСТЬ другое имя, например «Студенческий_билет». Однако, все параметры атрибутов внешнего ключа таблицы (тип, максимальная длина) должны полностью совпадать с аналогичными параметрами первичного ключа другой таблицы, с которой она связана.
Внешний ключ может ссылаться и на один из ключей той же таблицы БД, к которой он принадле-жит (не на себя самого – это бессмысленно). В этом случае внешний ключ называется рекурсивным.
Рассмотрим чуть более сложный пример связей между таблицами в базе данных. В этих таблицах хранится информация о книгах и их авторах. На рис. 1 приведена структура таблиц и показаны связи между ними. Таблица TITLEAUTHOR содержит идентификационные номера книг, их авторов, а также некоторую другую информацию. Информация о названиях книг, их тиражах, ценах, описаниях книг и т. д. хранится в таблице TITLES. Информация об именах и фамилиях авторов, их адресах, телефонах и данные о контрактах с ними хранятся в таблице AUTHORS.
Рис. 1 Связывание таблиц
Таблица TITLEAUTHOR содержит два столбца, используемых в качестве внешних ключей. Имена этих столбцов au_id и title_id (напротив них в структуре таблицы стоит значок ключа). В таблицах TITLES и AUTHORS выбрано по одному столбцу в качестве первичного ключа. Имена этих столбцов, соответственно, title_id и au_id. Установлена связь столбца title_id таблицы TITLEAUTHOR (внешний ключ таблицы TITLEAUTHOR) со столбцом title_id таблицы TITLES (первичный ключ таблицы TITLES) и связь столбца au_id таблицы TITLEAUTHOR (внешний ключ таблицы TITLEAUTHOR) со столбцом au_id таблицы AUTHORS (первичный ключ таблицы AUTHORS). В данном случае таблицы AUTHORS и TITLES являются главными таблицами по отношению к подчинённой таблице TITLEAUTHOR. В главных таблицах имеются первичные ключи, на которые ссылаются внешние ключи подчинённой таблицы. Зачастую (как в рассматриваемом примере) главные таблицы выступают в каче-стве справочников, которые используются для получения информации, на которую ссылаются данные в подчинённой таблице.
Когда пользователю необходимо получить список книг, написанных определённым автором, он сначала находит идентификационный номер автора (значение в столбце первичного ключа au_id) в таблице AUTHORS. Затем в таблице TITLEAUTHOR находятся все строки, у которых значение в столбце внешнего ключа au_id, ссылающегося на первичный ключ таблицы AUTHORS, равно найденному идентификационному номеру автора. В результате, будет получено несколько строк, содержащих идентификационные номера книг, написанных автором. Далее можно получить полную информацию о книгах из строк таблицы TITLES, содержащих во внешнем ключе (поле title_id) идентификационные номера книг из столбца title_id таблицы TITLEAUTHOR.