#sql #composite-primary-key
#sql #составной первичный ключ
Вопрос:
Хотя я уже некоторое время работаю с запросами к базам данных SQL, я все еще новичок в создании хороших таблиц. С чем я часто сталкиваюсь, так это с первичными ключами.
В таблице, которую я создаю сейчас для регистрации ошибок на некотором оборудовании сигнализации, мне нужно 5 столбцов. Столбцы park
и code
однозначно идентифицируют сайт (хотя park
столбцом является atm. не используется). Затем есть serial
столбец, идентифицирующий рассматриваемое оборудование, и error
содержащий код ошибки. Наконец, есть timestamp
для того, когда регистрируется ошибка.
На каждом сайте установлено несколько разных устройств, и одно из устройств может сообщать о нескольких ошибках. Когда ошибка исправлена, строка удаляется из таблицы.
Таким образом, чтобы однозначно идентифицировать ошибку, нам нужно проверить park
, code
, serial
и fault
. Все это кажется хорошими кандидатами для индексов, основанных на запросах, которые, вероятно, будут выполняться. Однако мне кажется неправильным определять все это как объединенный первичный ключ, в конце концов, это почти все столбцы в таблице!
Я несколько раз сталкивался с подобными проблемами, и я никогда не чувствовал, что нашел хорошее решение. Кто-нибудь может предложить несколько хороших практик для подобных таблиц, где большинство (или даже все) столбцов необходимы для уникальной идентификации строки?
Комментарии:
1. Какую СУБД вы используете? (Возможно, также стоит упомянуть физические соображения, которые зависят от этого)
2. Что касается случая в примере, я страдаю от SQL Server 2000, хотя я боролся с аналогичными проблемами в MySQL и PostgreSQL.
3. Перед вами два варианта: естественный составной ключ или суррогатный ключ с составным уникальным ограничением. Проблема в том, что, похоже, нет определенного решения. Пуристы БД будут выступать за PK (отсутствие дополнительного «искусственного» столбца), те, кто привык к частым изменениям в своей модели, предпочтут SK U…
Ответ №1:
Многие люди просто скажут вам добавить идентификационный номер в эту таблицу и сделать его первичным ключом.
Я не из таких людей.
Если столбцы {park, code, serial, fault} необходимы для уникальной идентификации строки и, таким образом, для предотвращения дубликатов, то СУБД должна это знать. Вы информируете СУБД об этом требовании одним из двух способов.
- ПЕРВИЧНЫЙ КЛЮЧ (парк, код, серийный номер, ошибка)
- НЕ является УНИКАЛЬНЫМ ЗНАЧЕНИЕМ NULL (парк, код, серийный номер, ошибка)
В некоторых случаях имеет смысл использовать меньший суррогатный ключ (идентификационный номер) в качестве первичного ключа. Это не освобождает вас от ответственности за информирование СУБД об истинном положении дел. (С NOT NULL UNIQUE (park, code, serial, fault)
.) Однако я не думаю, что это применимо к вашей ситуации.