Проектирование базы данных: выбор первичного ключа

Хорошая модель и правильный проект базы данных формируют основу информационной системы. Построение слоя данных - часто первый критичный шаг в направлении создания новой системы, который правомерно требует внимания к деталям и тщательного планирования. База данных, как и любая компьютерная система, является моделью небольшой части реального мира. И, как любая модель, это - узкое представление, которое значительно упрощает сложность реальной вещи. Современные системы баз данных основываются на реляционной модели хранения и извлечения данных. Название происходит от слова relationship - отношение между столбцами в таблице (а не из того, что Вы можете связать таблицы между собой). Другими словами, "реляционный" означает, что несколько значений, которые принадлежат одной и той же строке, являются связанными.

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

Естественные Ключи

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

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

Есть множество желательных (не обязательно требуемых) характеристик первичного ключа, которых зачастую не имеют естественные идентификаторы:
  • Уникальные значения: первичный ключ должен уникально идентифицировать каждую строку в таблице.
  • Неинтеллектуальный: первичный ключ не должен иметь смыслового содержания. Другими словами, он не должен описывать характеристики сущности. Идентификатор клиента 398237 обычно более предпочтителен по сравнению с Майкл Дж. Малоун.
  • Неизменяемость во времени: значение первичного ключа никогда не должно меняться. Изменение значения первичного ключа означает, что Вы меняете идентичность сущности, что не имеет смысла. Неинтеллектуальные ключи предпочтительны, поскольку они с меньшей вероятностью подвержены изменениям.
  • Одноатрибутность: первичный ключ должен состоять из минимально возможного числа атрибутов. Желательно иметь одноатрибутные первичные ключи, поскольку с ними легче работать в приложениях, и они упрощают создание внешних ключей.
  • Числовой: легче управлять уникальными значениями, если они являются числовыми. Большинство систем базы данных имеют внутренние процедуры, которые поддерживают автоинкрементируемые атрибуты для первичных ключей. Хотя эти средства полезны, не используйте их бездумно.
Для каждого из этих правил есть исключения. Например, составные первичные ключи особенно полезны как идентификаторы в соединяемых таблицах, моделируя отношение "многие к многим". И наоборот, подходящий однозначный естественный ключ не должен игнорироваться только потому, что он не является числовым.

Суррогатные ключи

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

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

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

Заключение

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