Уникальный ключ

В реляционных СУБД уникальный ключ — это потенциальный ключ (также в русскоязычных источниках используется термин возможный ключ[1]), который не является первичным ключом отношения. Все потенциальные ключи отношения могут однозначно идентифицировать записи отношения, но только один из них используется в качестве первичного ключа отношения[1]. Остальные ключи-кандидаты называются уникальными ключами, поскольку они могут однозначно идентифицировать запись в отношении. Уникальные ключи могут состоять из нескольких столбцов. Уникальные ключи также называются альтернативными ключами. Уникальные ключи являются альтернативой первичному ключу отношения. Как правило, уникальные ключи имеют ограничение UNIQUE.

Обзор понятия

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

В самом простом определении «ключ — это уникальный идентификатор»[2], поэтому уникальный ключ — это плеоназм. Ключи, находящиеся в исходном объекте, уникальны в этом объекте. Ключи, переносимые в другую сущность, могут быть уникальными, а могут и нет, в зависимости от дизайна и того, как они используются в другой таблице. Внешние ключи могут быть первичными ключами в другой таблице; например, PersonID может стать EmployeeID в таблице Employee. В этом случае EmployeeID является как внешним ключом, так и уникальным первичным ключом, что означает, что таблицы имеют отношение 1:1. В случае, когда сущность-лицо содержит идентификатор биологического отца, не ожидается, что идентификатор отца будет уникальным, поскольку у отца может быть более одного ребёнка.

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

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

В принципе на любой ключ могут ссылаться внешние ключи. Некоторые СУБД SQL допускают задание ограничения (constrain) внешнего ключа только по отношению к первичному ключу, но большинство систем разрешают ограничению внешнего ключа ссылаться на любой ключ таблицы.

Определение в SQL

Определение уникального ключа в синтаксисе SQL:

  ALTER TABLE <table identifier> 
      ADD [ CONSTRAINT <constraint identifier> ] 
      { PRIMARY KEY | UNIQUE } ( <column name> [ {, <column name>}... ] )

Также, ключи могут быть определены при создании таблицы CREATE TABLE.

  CREATE TABLE table_name (
     id_col   INT,
     col2     CHARACTER VARYING(20),
     key_col  SMALLINT NOT NULL,
     ...
     CONSTRAINT key_unique UNIQUE(key_col),
     ...
  )
  CREATE TABLE table_name (
     id_col  INT  PRIMARY KEY,
     col2    CHARACTER VARYING(20),
     ...
     key_col  SMALLINT NOT NULL UNIQUE,
     ...
  )

Различия между первичным и уникальным ключом

Свойства первичного ключа

В первичном ключе не допускается значение NULL (его нельзя определить для столбцов, допускающих такое значение). Каждая таблица не может иметь более одного первичного ключа[3]. В некоторых СУБД первичный ключ по умолчанию создаёт кластеризованный индекс. В практических реализациях SQL первичный ключ в некоторых таблицах может отсутствовать[1].

Свойства уникального ключа

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

Каждая таблица может иметь несколько уникальных ключей[3]. В некоторых СУБД уникальное ограничение по умолчанию создаёт некластеризованный индекс.

Обратите внимание, что в отличие от ограничения PRIMARY KEY ограничение UNIQUE не означает NOT NULL для столбцов, участвующих в ограничении. Если нужно запретить значение NULL, необходимо указать ограничение NOT NULL дополнительно. Можно установить ограничения UNIQUE для столбцов, допускающих значение NULL, но в стандарте SQL указано, что ограничение не гарантирует уникальность столбцов, допускающих значение NULL (уникальность не применяется для строк, в которых любой из столбцов содержит значение NULL).

В соответствии со стандартом SQL[4] ограничение уникальности не обеспечивает уникальность при наличии значений NULL и поэтому может содержать несколько строк с идентичными комбинациями пустых и непустых значений — однако не все СУБД реализуют эту функцию в соответствии со стандартом SQL[5][6].

См. также

Ссылки

Примечания

Категории