Нормализация реляционных баз данных - Ключ

ОГЛАВЛЕНИЕ

 

Ключ

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

Вспомним ранее пройденный материал. Мы уже знаем, что отношение состоит из кортежей (или, более простыми словами, таблица состоит из строк, хотя это не вполне корректно). Естественно, что функции системы управления базами данных не исчерпываются простым накоплением данных; мы хотим также манипулировать содержимым БД. Для этого необходимо иметь возможность каким-то образом отличать кортежи друг от друга.

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

Определение. Пусть r - отношение, R - его схема. Ключом K отношения r называется подмножество атрибутов {A1, A2, , Am} <= R, обладающее следующим свойством: для любых двух различных кортежей t1 и t2 из r существует A€K такое, что t1(A) != t2(A). Т.е. не существует двух кортежей, которые бы имели одно и то же значение на всех атрибутах из K. Таким образом, K-значение кортежа однозначно идентифицирует кортеж в r. (Из-за ограничений символьного набора, доступного при публикации статьи на сайте, мне пришлось воспользоваться следующими обозначениями: здесь и далее символ "<=" означает "является несобственным подмножеством", символ "€" "означает принадлежит множеству", а "!=" означает "не равно").

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

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

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

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

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

Мы пытаемся спасти положение, расширяя ключ на столбцы "Имя" и "Отчество". Программа вновь оживает, но при этом мы знаем, что это всего лишь заметание мусора под ковер: проблема не решена окончательно, а всего лишь уменьшена вероятность очередного сбоя по причине нарушения уникальности ключа.

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

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

Здесь возникает довольно интересный вопрос. Предположим, что наше отношение r имеет в качестве ключа множество атрибутов {A1, A2, , Am}. Добавим к этому множеству еще один атрибут, Am+1. Является ли множество {A1, A2, , Am, Am+1} ключом r? Формально - безусловно является, поскольку ключ по-прежнему однозначно идентифицирует кортежи r. Однако чувствуется какой-то подвох. Во-первых, добавленный атрибут в ключе явно лишний, поскольку ключ справлялся с задачей идентификации и без него. Во-вторых, есть опасность, что одним атрибутом это добавление не ограничится, и нам придется иметь дело с целым множеством ключей. Как же ограничить ключевое множество атрибутов действительно необходимым минимумом?

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

Ключом K отношения r называется подмножество атрибутов {A1, A2, , Am} <= R, такое, что для любых двух различных кортежей t1 и t2 из r выполняется t1(K) != t2(K), и при этом ни одно собственное подмножество K<K не обладает этим свойством.

Множество SK называется суперключом отношения r, если K - ключ r и K<=SK. Очевидно, что первоначально введенное определение ключа на самом деле относится к суперключу.