Открыть сервис

Внешний ключ

Внешний ключ (англ. foreign key) — это столбец или набор столбцов в реляционной базе данных, значения которых соответствуют значениям первичного ключа (или уникального ключа) в другой (или той же самой) таблице. Внешние ключи служат для установления и поддержания связей между таблицами, обеспечивая ссылочную целостность данных. Механизм внешнего ключа гарантирует, что значения в данном столбце (или комбинации столбцов) должны либо присутствовать в связанном столбце родительской таблицы, либо быть равными NULL (если допускается отсутствие связи).

История и стандартизация

Концепция внешнего ключа была разработана в рамках реляционной модели данных, предложенной Эдгаром Коддом в 1970 году. В своей работе «A Relational Model of Data for Large Shared Data Banks» Кодд сформулировал требования к целостности данных, включая целостность сущностей (первичный ключ) и ссылочную целостность (внешний ключ). Практическая реализация внешних ключей появилась в коммерческих системах управления базами данных (СУБД), начиная с 1980-х годов, например, в Oracle, DB2 и Ingres.

Механизм внешнего ключа был стандартизирован в языке SQL (ISO/IEC 9075) начиная с SQL-92, хотя ранние реализации в некоторых СУБД (например, MySQL версии 3.23) поддерживали синтаксис внешнего ключа, но игнорировали его семантику. Современные реляционные СУБД (PostgreSQL, Microsoft SQL Server, MySQL/InnoDB, Oracle, SQLite) в полной мере поддерживают внешние ключи, обеспечивая проверку ограничений на стороне сервера.

Определение и синтаксис

В языке SQL внешний ключ объявляется с помощью ограничения FOREIGN KEY при создании или изменении таблицы. Основной синтаксис выглядит следующим образом:

``sql CREATE TABLE дочерняя_таблица ( id INTEGER PRIMARY KEY, родитель_id INTEGER, FOREIGN KEY (родитель_id) REFERENCES родительская_таблица(ключевой_столбец) ); ``

Здесь:

Внешний ключ может ссылаться не только на первичный ключ родительской таблицы, но и на любой столбец или комбинацию столбцов, для которых определён уникальный ограничитель (уникальный ключ). Если внешний ключ состоит из нескольких столбцов, их количество и порядок должны совпадать с количеством и порядком столбцов в ссылочном ограничении родительской таблицы.

Ограничения ссылочной целостности

При объявлении внешнего ключа CУБД автоматически проверяет соблюдение следующих правил:

  1. Запрет вставки или обновления: В дочернюю таблицу нельзя вставить строку, значение внешнего ключа которой отсутствует в родительской таблице (если только оно не равно NULL и это допускается). Аналогично, при обновлении значения внешнего ключа в дочерней таблице новое значение должно существовать в родительской таблице.
  2. Защита при удалении или обновлении в родительской таблице: По умолчанию (в зависимости от поведения, заданного опциями ON DELETE и ON UPDATE) при попытке удалить или изменить ключевое значение в родительской таблице, на которое есть ссылки в дочерней таблице, СУБД либо запрещает операцию, либо автоматически выполняет одно из предопределённых действий.

Поведения при удалении и обновлении

Стандарт SQL определяет несколько опций, которые задаются после REFERENCES:

Выбор подходящего поведения зависит от бизнес-логики приложения. Например, для таблицы «Заказы» и «Позиции заказа» логичным является ON DELETE CASCADE, так как удаление заказа должно приводить к удалению всех его позиций. В то же время для таблицы «Сотрудники» и «Отделы» может использоваться SET NULL при удалении отдела, чтобы сотрудники не терялись, а получали неопределённое значение отдела.

Типы связей и проектирование

Внешние ключи позволяют реализовать три основных типа связей между таблицами:

  1. Один-ко-многим (1:M) — наиболее распространённый тип. Один первичный ключ в родительской таблице может быть связан с несколькими строками в дочерней таблице. Например, таблица «Категории» (один канал) и таблица «Товары» (множество товаров в категории). В дочерней таблице в столбце внешнего ключа хранится значение первичного ключа родительской таблицы.
  2. Многие-ко-многим (M:N) — прямая реализация внешним ключом невозможна; для этого создаётся связующая таблица, в которой хранятся два внешних ключа, ссылающихся на первичные ключи обеих соединяемых таблиц. Например, таблицы «Студенты» и «Курсы» соединяются через таблицу «Записи на курсы», содержащую student_id и course_id.
  3. Один-к-одному (1:1) — реализуется путём объявления уникального ограничения на столбец внешнего ключа в дочерней таблице, что гарантирует, что каждая строка родительской таблицы может иметь не более одной связанной строки.

Внешний ключ может ссылаться на ту же таблицу, где он определён (рекурсивный внешний ключ). Пример: в таблице «Сотрудники» может быть столбец manager_id, являющийся внешним ключом к столбцу employee_id той же таблицы, что позволяет организовать иерархическую структуру подчинения.

Влияние на производительность

Наличие внешних ключей накладывает на СУБД дополнительные проверки при каждой операции вставки, обновления или удаления в связанных таблицах. Это может снижать производительность, особенно в высоконагруженных системах с интенсивными транзакциями. Однако преимущества в виде гарантии целостности данных часто перевешивают накладные расходы.

Для повышения производительности разработчики могут:

Отличия от других типов ограничений

Внешний ключ следует отличать от:

Примеры использования в реальных системах

В российских информационных системах внешние ключи широко применяются для организации реляционных структур. Например:

Критика и ограничения

Некоторые разработчики, особенно в области NoSQL-систем или при проектировании высоконагруженных приложений, могут отказываться от использования внешних ключей, предпочитая обеспечивать ссылочную целостность на уровне прикладного кода. Это может быть связано с требованиями к горизонтальному масштабированию (шардированию), при котором проверка внешних ключей становится сложной и затратной, или с использованием базы данных, не поддерживающей их (например, MyISAM для MySQL).

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

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →