В чем разница между первичным ключом и идентичностью?
Какой смысл использовать, когда оба идентифицируют уникальную строку? Почему люди используют столбец идентификации в качестве первичного ключа? Кто-нибудь может кратко описать ответ?
4 ответа
Первичный ключ - это логическая концепция - это средство, с помощью которого вы будете уникально идентифицировать каждую запись в таблице. Существует несколько типов первичного ключа - естественный ключ использует атрибут данных из бизнес-домена, который гарантированно должен иметь требования к первичному ключу (уникальный, не нулевой, неизменный), например, номер социального страхования, составной ключ является ключ состоит из нескольких столбцов (часто используемых в отношениях "родитель-ребенок"), а суррогатный ключ создается системой; это может быть автоинкремент или столбец идентификаторов.
Идентичность является типом данных. Это очень полезно для использования в качестве суррогатного первичного ключа, потому что он имеет все необходимые атрибуты. Маловероятно, что вы используете тип идентификатора для других целей, кроме как в качестве первичного ключа, но ничто не мешает вам сделать это.
Таким образом, не все первичные ключи используют тип данных идентификации, и не все столбцы идентификации являются первичными ключами.
Первичный ключ - это своего рода уникальный ключ. Фактически это ограничение (ограничение), что значения для определенного столбца (или, в общем случае, набора столбцов) не могут быть одинаковыми в разных строках (даже если вручную / явно заданы одинаковые значения с помощью вставки / обновления),
Первичный / уникальный ключ не обязательно должен быть автоматически увеличен. На самом деле это вовсе не обязательно целое число - это может быть текст или другой тип.
Первичный ключ немного строже обычного уникального ключа, который обычно подразумевает NOT NULL
и, кроме того, в таблице разрешен только один первичный ключ (в то время как в дополнение к первичному ключу допускается использование нескольких уникальных ключей в таблице).
Создание первичного / уникального ключа обычно неявно создает индекс, чтобы ускорить поиск и проверку ограничений по этим столбцам.
Например, если столбец my_column
из my_table
помечен как первичный или уникальный ключ, вы не можете сделать это:
INSERT INTO my_table (my_column, other_column, third_column)
VALUES (10, …, …);
INSERT INTO my_table (my_column, other_column, third_column)
VALUES (10, …, …); -- the same value for my_column again
Идентичность в вашей RDBMS - это то, что другие RDBMS могут называть auto_increment или serial. Это просто особенность, заключающаяся в том, что во время операции вставки строки определенный столбец, если явно не задано какое-либо значение, автоматически инициализируется (чаще всего) последовательными целочисленными значениями.
Например, если столбец my_column
из my_table
помечен как auto_increment/serial/identity, вы можете сделать это:
INSERT INTO my_table (other_column, third_column) VALUES (…, …);
-- not specifying any value for my_column manually,
-- it'll be initialized automatically to some value
-- (usually an increasing integer sequence)
Auto_increment / serial / identity обычно не гарантирует строгой последовательности автоматических значений (особенно в случае прерванных транзакций).
Конкретно документация для TRANSACT-SQL говорит, что идентичность не гарантирует:
- уникальность (используйте уникальные / первичные ключи для обеспечения этого);
- строгая последовательность.
Обновление: как предложено a_horse_with_no_name, "удостоверение", по-видимому, является не только именем общей функции auto_increment/serial/identity в определенных СУБД (например, Microsoft SQL Server), но также и именем, определенным стандартом ANSI SQL.
AFAIK, он не сильно отличается от того, что я описал выше (об общей функции auto_increment/serial/identity в реализациях). Я имею в виду, что он делает значения столбцов автоматически инициализированными с целочисленной последовательностью, но не гарантирует уникальность и строгую последовательность.
Тем не менее, я предполагаю, что, в отличие от столбцов auto_increment / serial в MySQL/PostgreSQL, стандарт ANSI-SQL generated always as identity
столбец не позволяет устанавливать его значения вручную в INSERT или UPDATE (только автоматически).
В таблице базы данных каждая строка должна быть уникальной, и вы должны иметь возможность уникально идентифицировать конкретную строку.
В данной таблице может быть один или несколько столбцов с уникальными значениями, поэтому любой из этих столбцов может выполнять эту работу. Также может быть два или более столбцов, которые, хотя и не уникальны сами по себе, образуют уникальную комбинацию. Это тоже подойдет.
Любой столбец или комбинация столбцов, которые могут однозначно идентифицировать строку, называется ключом-кандидатом. В принципе, вы можете выбрать любой ключ, который вам нравится, но вы должны убедиться, что уникальность сохраняется. Например, в небольшой таблице лиц данное имя может быть уникальным, но вы рискуете его унести со следующим дополнительным человеком.
Первичный ключ - это ключ-кандидат, который вы назначаете в качестве предпочтительного ключа. Например, таблица лиц может иметь ряд уникальных атрибутов, таких как адрес электронной почты, номер мобильного телефона и другие. Первичный ключ - это атрибут, который вы предпочитаете другим.
Следующее не является строго обязательным, но это хорошая практика для хорошего первичного ключа:
- Первичный ключ не должен меняться
- Первичный ключ не должен быть переработан
По этой причине первичный ключ не должен иметь никакого реального значения, поэтому никогда не должно быть причин для его изменения или повторного использования. В результате первичный ключ часто является произвольным кодом, единственное реальное значение которого состоит в том, что он идентифицирует строку. Если ключ используется исключительно для идентификации и не имеет другого значения, его часто называют суррогатным ключом.
Вы можете приложить некоторые усилия для создания произвольных кодов. Иногда они следуют сложным схемам, которые можно использовать для проверки их достоверности.
Если вы хотите использовать более ленивый подход, вы можете использовать порядковый номер. Однако, вопреки моему предыдущему совету, он действительно имеет значение: он строго последовательный, поэтому вы можете узнать, какая строка была добавлена после другой, но не точно когда. Однако этот факт не изменится - он не изменится в стоимости и не будет использоваться повторно - поэтому он все еще довольно стабилен.
Фактически столбец идентификаторов - это порядковый номер. Он генерируется автоматически и очень полезен, если вы хотите произвольный код для вашего первичного ключа. К сожалению, это очень поздно для очень медленных стандартов, поэтому у каждой СУБД была своя нестандартная вариация:
- MySQL называет это
AUTO_INCREMENT
- SQLite называет это
AUTOINCREMENT
- MSSQL называет это IDENTIY ()
- MSACCESS называет это
AUTONUMBER
- PostgreSQL называет это
SERIAL
и у каждого есть свои причуды.
Совсем недавно (я полагаю, что в 2003 году) оно было добавлено в стандарты в виде:
int generated by default as identity
но это только начало появляться в PostgreSQL и Oracle. Это использование IDENTITY
ведет себя иначе, чем Microsoft.
Первичному ключу требуется уникальный номер и значение первичного ключа не может быть нулевым, которое можно получить по идентификатору, и нам не нужно вручную добавлять каждую новую запись, которая добавляется в таблицу.
когда запись не может быть вставлена в таблицу по какой-то причине, что время также увеличивается в SQL Server.