Первичный ключ задается ограничением PRIMARY KEY. При продуманной схеме базы данных первичный ключ служит неизменным уникальным идентификатором записей. Если ключ объявляется первичным, это свидетельствует о том, что значения в нем будут изменяться редко.
Лучше всего воспринимать ограничение PRIMARY KEY как комбинацию ограничений NOT NULL и UNIQUE, т. к. при этом требуется, чтобы значения указанных полей не были равны NULL и при этом не повторялись. Рассмотрим следующий пример, в котором в качестве первичного ключа объявлено поле SKU.
Первичные ключи
Первичные ключи
В этом случае вследствие того, что столбец sku определяется как первичный ключ, MySQL будет отслеживать дублирование значений в этом поле и появление значений NULL. Это позволяет администратору базы данных обеспечить, чтобы все хранящиеся в таблице записи имели уникальное значение в поле sku, а значит, и большую степень целостности хранимых данных.
Ограничения PRIMARY KEY могут задаваться как для одного поля, так и для нескольких полей сразу. Рассмотрим следующий пример, демонстрирующий создание таблицы, содержащей составной первичный ключ.
Первичные ключи
В данном случае ограничения этой таблицы разрешают повторение IP-адреса узла или порта, но не комбинации того и другого сразу. Это удобно тогда, когда запись должна идентифицироваться уникальным образом по совокупности атрибутов, а не по какому-либо одному атрибуту.
Внешние ключи
Фундаментальной возможностью такой реляционной базы данных, как MySQL, является возможность создания связей между таблицами, из которых состоит эта база данных. Имея возможность легко связывать таблицы между собой, реляционная СУБД позволяет анализировать данные самыми разнообразными способами и хранить их в систематизированном виде при минимальной избыточности.
Первичные ключи
Ключ с другим названием
В MySQL термины "ключ" и "индекс" являются эквивалентными. Таким образом, поля, входящие в PRIMARY KEY, автоматически индексируются во всех таблицах MySQL, в то время как ключ типа FOREIGN KEY должен быть проиндексирован пользователем явным образом.
Эти связи реализуются с помощью внешних ключей. При этом существенно, чтобы все поля, имеющие одинаковое значение во всех задействованных в связях таблицах, служили точками связи записей разных таблиц. Посредством внешних ключей образуется связь типа "один к одному" - когда запись одной таблицы может быть связана с одной и только одной записью другой таблицы, - или типа "один ко многим" - когда запись одной таблицы может быть связана сразу с несколькими записями другой таблицы.
На рис. 8.1 показана связь типа "один к одному": услуга и связанное с ней описание, причем связь между ними образуется посредством уникального поля serviceID.
На рис. 8.2 показана связь типа "один ко многим": компания и список ее филиалов, связь между которыми осуществляется через уникальное поле companyID.
Если каждое значение внешнего ключа соотносится с определенным полем другой таблицы и это соотношение является уникальным, о системе говорят, что она находится в состоянии ссылочной целостности. Другими словами, если поле представлено во всех таблицах один и только один раз, а изменение этого поля отображается во всех других таблицах, считается, что ссылочная целостность обеспечена.
Первичные ключи
 Эта концепция ссылочной целостности является основной концепцией при разработке баз данных, содержащих более одной таблицы. Когда внешние ключи используются для обеспечения связи между таблицами, ссылочная целостность накладывает ограничения относительно добавления новых записей и обновления уже существующих записей. 
Например, когда таблица принимает значения только определенного типа для определенных полей, а другая таблица использует это поле в качестве своего внешнего ключа, это автоматически накладывает определенные ограничения на задействованные таблицы. Кроме того, ссылочная целостность подразумевает, чтобы любые изменения в поле, которое используется в качестве внешнего ключа, - удаление или новое добавление - немедленно отображались во всех связанных для этого поля таблицах.
Многие, но не все современные СУБД решают эту задачу автоматически. Например, если вы работаете с СУБД Microsoft Access, вам придется заниматься подобными проблемами. В случае, если СУБД автоматически не выполняет эту работу, задача обеспечения ссылочной целостности ложится на плечи разработчика, которому приходится вручную обновлять все связанные таблицы для отображения изменений в значениях внешних ключей.
С этой точки зрения MySQL находится на полпути, разрешая использование внешних ключей, но не используя их для проверки целостности данных для всех типов таблиц, за исключением таблиц типа InnoDB (начиная с MySQL 3.23.44). И причина такого положения относится исключительно к прагматической области: проведение проверок целостности по всем связям с использованием внешних ключей при каждом выполнении операций INSERT, UPDATE и DELETE, требует много времени и ресурсов, а значит, может отрицательно влиять на производительность, особенно при работе со сложными или запутанными деревьями связи. Таким образом, пользователи вольны выбирать такую комбинацию, которая наиболее подходит для решения их задач.
В следующем примере поле employees.fk_department является внешним ключом, связанным с первичным ключом таблицы departments.id. Обратите внимание на то, каким образом эта связь объявлена модификатором FOREIGN KEY...REFERENCES. Здесь часть FOREIGN KEY задает одну часть связи (имя поля в текущей таблице), а часть REFERENCES задает другую часть связи (имя поля в связанной таблице).
При создании таблицы внешний ключ объявляется во многом аналогично тому, как объявляются первичные ключи, т.е. с использованием модификатора FOREIGN KEY... REFERENCES. В следующем примере демонстрируется создание двух таблиц типа InnoDB, связанных друг с другом связью "один ко многим" по идентификатору отдела.
Первичные ключи