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

1.3.2. Реляционные ключи

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

Любое множество атрибутов отношения, позволяющее однозначно идентифицировать каждый кортеж этого отношения, называется суперключом.

Например, для таблицы предметов суперключом является условный номер предмета. Также суперключом является набор атрибутов «наименование» + «цена». А вот атрибут «наименование» суперключом не является, так как не позволяет различить предметы, имеющие одно наименование, но разную цену (а такие предметы следует различать и учитывать отдельно). С другой стороны, набор атрибутов «наименование» + «ед. измерения» + «цена» также является суперключом. И набор всех атрибутов таблицы – суперключ. Легко заметить, что понятие суперключа содержит некоторую избыточность. Поэтому рассмотрим еще одно, более строгое понятие.

Суперключ, который не содержит подмножества атрибутов, также являющегося суперключом, называется потенциальным ключом.

В таблице предметов имеется два потенциальных ключа: «условный номер предмета» и «наименование» + «цена». А, например, суперключ «наименование» + «ед. измерения» + «цена» потенциальным ключом не является, поскольку содержит подмножество атрибутов, предсталяющее собой суперключ: «наименование» + «цена». Понятия суперключа и потенциального ключа совпадают в том, что оба они обладают свойством уникальности, но при этом только потенциальный ключ обладает свойством неприводимости в том смысле, что его нельзя свести к другому суперключу.

Потенциальных ключей в отношении может быть несколько, но для уникальной идентификации кортежей необходимо выбрать какой-то один из них.

Потенциальный ключ, который выбран для уникальной идентификации кортежей некоторого отношения, называется первичным ключом этого отношения (ПК, Primary Key, PK). При этом все остальные потенциальные ключи становятся альтернативными ключами.

Например, если первичный ключ таблицы предметов определить по атрибуту условного номера, то совокупность атрибутов «наименование» + «цена» следует считать альтернативным ключом.

Возникает вопрос: каждое ли отношение (каждая ли таблица) должны иметь первичный ключ. Мнения по этому поводу расходятся. Противоречие здесь обусловлено расхождением математики и теории баз данных. С точки зрения математики, в отношении не может быть двух одинаковых строк. Соответственно, отношение всегда будет иметь первичный ключ, который в худшем случае будет состоять из всех атрибутов этого отношения.

Для баз данных положение несколько другое. Возьмем, например, таблицу проводок. Можно предположить, что набор всех ее столбцов будет первичным ключом. Однако легко представить себе ситуацию, когда предмет одного и того же наименования будет передаваться между одними и теми же лицами несколько раз за день в одинаковом количестве (один и тот же человек взял пачку бумаги со склада два раза за день). Конечно, проблема первичного ключа может быть здесь решена путем замены атрибута даты на атрибут точного времени проводки или добавлением атрибута условного номера проводки. Вопрос в том – а если такая необходимость? Нужен ли вообще первичный ключ для таблицы проводок? Попробуем разобраться.

В каждой паре связанных таблиц можно указать родительскую (главную, Master) и дочернюю (подчиненную, Detail) таблицу. При этом каждая запись дочерней таблицы должна ссылаться на единственную соответствующую ей запись родительской таблицы. А любая запись родительской таблицы может быть связана с несколькими записями дочерней. Например, для связи таблиц предметов и наличия имеем следующую схему:

Предметы Наличие

Усл. №

Наимен.

Ед. изм.

Цена

Лицо

Предмет

Кол-во

. . .

. . .

12

Стул

шт

8 00.00

3

7

2

23

Кресло

шт

2000.00

3

12

8

7

Стол

шт

1600.00

17

12

3

. . .

9

7

5

9

12

20

. . .

Такую связь таблиц принято называть один-ко-многим (или многие-к-одному, если посмотреть на связь с другой стороны). То есть, одной строке родительской таблицы может соответствовать множество записей дочерней, но каждой записи дочерней таблицы всегда соответствует только одна запись родительской.

Связи типа один-ко-многим – это основной вид связей в реляционных базах данных. Гораздо реже встречаются связи типа один-к-одному, при которых одной родительской записи соответствует одна дочерняя и наоборот. Такого рода связи возникают, например, в тех случаях, когда отношение делится на две таблицы с тем, чтобы вынести в отдельную таблицу редко используемые атрибуты или атрибуты, к которым необходимо ограничить доступ (фото, пароли и т.п.).

При проектировании БД часто приходится иметь дело со связями типа многие-ко-многим. Например, подотчетные лица отвечают за хранение предметов (у одного п/о лица хранится множество предметов и один и тот же предмет может быть у нескольких лиц). Однако такого рода связи не могут быть реализованы в рамках реляционной модели данных и на этапе логического проектирования заменяются парами связей типа один-ко-многим.

Итак, основной вид связей в РБД это связи типа один-ко-многим. Очевидно, что для их реализации необходимо иметь возможность найти в родительской таблице ту единственную запись, которая соответствует текущей дочерней записи. То есть, в родительском отношении обязательно должен присутствовать механизм уникальной идентификации. Отсюда следует вывод.

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

Замечание. Одна и та же таблица в разных своих связях может выступать и как родительская и как дочерняя. Например, таблица лиц в своих связях с таблицами типов лиц и подразделений является дочерней, а в связях с таблицами наличия и проводок – родительской.

Для отношений, которые во всех своих связях выступают как дочерние, однозначной необходимости в первичном ключе нет. Тем не менее, и для них могут определяться ПК. Например, в таблице наличия, которая во всех своих связях выступает как дочерняя, стоит создать ПК по полям «лицо» + «предмет» для исключения возможности появления в таблице нескольких записей о наличии одного и того же предмета у одного и того же лица. В серверных БД обычно первичные ключи определяются для всех таблиц потому, что в противном случае будет невозможно удалить только одну строку из нескольких одинаковых строк (работа в серверных БД ведется с множествами строк, а не с отдельными записями, как в локальных БД).

Для реализации связей между таблицами недостаточно только первичных ключей. При ссылке из дочерней таблицы на родительскую необходимо указать значения полей первичного ключа, по которым будет найдена нужная родительская запись. Соответственно, дочерняя таблица должна включать в себя атрибуты ПК родительской таблицы. Например, если ПК таблицы предметов построен по условному номеру, то и в таблицах наличия и проводок должны указываться условные номера предметов. А если ПК таблицы предметов будет построен по полям «наименование» + «цена», то и в дочерних таблицах должны присутствовать эти поля.

Атрибуты первичного ключа родительского отношения, включаемые в дочернее для реализации его связи с родительским отношением, называются внешним ключом (ВК, Foreign Key, FK).

Внешние ключи, в отличие от первичных, свойством уникальности не обладают. Внешних ключей в таблице может быть несколько, тогда как первичный ключ всегда один. Например, в таблице наличия первичный ключ следует построить по полям «лицо» + «предмет». Эта же таблица будет иметь два внешних ключа: по полю «лицо» для связи с таблицей лиц и по полю «предмет» для связи с таблицей предметов. (Здесь ПК построен по полям внешних ключей, что характерно для слабых типов сущности).

Как отмечалось ранее, отношение может иметь несколько потенциальных ключей и только один из них должен быть выбран в качестве первичного. Сформулируем принципы, которыми следует руководствоваться при этом выборе.

  1. Первичный ключ должен обеспечивать уникальную идентификацию строк не только при текущем состоянии таблицы, но и с учетом всех возможных изменений в будущем.

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

  3. Атрибуты первичного ключа должны изменяться как можно реже. Дело в том, что всякое изменение атрибутов первичного ключа влечет за собой соответствующие изменения атрибутов внешних ключей. Например, если условный номер лица изменился с 5 на 25, то во всех соответствующих строках таблиц наличия и проводок значение 5 необходимо заменить значением 25.

С точки зрения сформулированных соображений, большой интерес представляют так называемые суррогатные ключи, которые строятся по семантически незначащим (не имеющим физического смысла) атрибутам типа условный номер (лица, предмета, …). Действительно, для такого рода ключей во всех СУБД предусмотрены специальные механизмы поддержания их уникальности. В PARADOX – это автоинкрементные поля, в InterBase/FireBird – генераторы, в Oracle – последовательности и т.д. Они имеют минимальный размер: формат целого числа. И нет каких-либо разумных причин для изменения их значений (какая разница для внутренних механизмов БД имеет ли предмет условный номер 5 или 5537676. Условный номер нужен только для реализации внутренних связей в БД и пользователь вообще не должен его видеть).

Однако, вряд ли можно согласиться с довольно часто встречающимся утверждением, что надо не задумываясь объявлять суррогатные ПК во всех создаваемых таблицах (например, ID столбцы в MS Access). Например, никакой пользы от суррогатного ключа в таблице наличия не будет. Уникальный индекс по полям «лицо» + «предмет» все равно создать придется, а дополнительное поле только увеличит объем таблицы, усложнит работу с ней и понимание связей в БД, не дав при этом никакого выигрыша. Поэтому суррогатные ключи следует применять «с пониманием», там, где они приносят выигрыш, оправдывающий уход от физического смысла связей в БД.