Внешний ключ (FOREIGN KEY) нужен для того, чтобы связать две разные таблицы между собой. Внешний ключ может ссылаться на любой столбец в родительской таблице. Однако общепринятой практикой является ссылка внешнего ключа на первичный ключ (primary key) родительской таблицы. Например:
Здесь поле customer_id в таблице Orders является FOREIGN KEY
, который ссылается на поле id в таблице Customers. Это означает, что значением customer_id (таблицы Orders) должно быть значение из столбца id (таблицы Customers).
Создание внешнего ключа
Теперь давайте посмотрим, как мы можем добавить ограничение FOREIGN KEY
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
-- Эта таблица не имеет внешнего ключа CREATE TABLE Customers ( id INT, first_name VARCHAR(40), last_name VARCHAR(40), age INT, country VARCHAR(10), CONSTRAINT CustomersPK PRIMARY KEY (id) ); -- Добавляем внешний ключ к полю customer_id. -- Внешний ключ ссылается на поле id таблицы Customers CREATE TABLE Orders ( order_id INT, item VARCHAR(40), amount INT, customer_id INT REFERENCES Customers(id), CONSTRAINT OrdersPK PRIMARY KEY (order_id) ); |
Здесь столбец customer_id таблицы Orders ссылается на столбец id таблицы Customers.
Примечание: Вышеприведенный код создания внешнего ключа может отличаться в некоторых СУБД.
Вставка данных в таблицу с внешним ключом
Попробуем вставить данные в таблицу с внешним ключом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
-- Сначала вставляем данные в таблицу без внешнего ключа INSERT INTO Customers VALUES (1, 'John', 'Doe', 31, 'USA'), (2, 'Robert', 'Luna', 22, 'USA'); -- Первая операция вставки данных проходит успешно INSERT INTO Orders VALUES (1, 'Keyboard', 400, 2), (2, 'Mouse', 300, 2), (3, 'Monitor', 12000, 1); -- Вторая операция вставки данных приводит к ошибке, поскольку customer_id со значением 7 не существует INSERT INTO Orders VALUES (4, 'Keyboard', 400, 7); |
Зачем использовать внешний ключ?
Две главные причины:
Нормализация данных. FOREIGN KEY
помогает нормализовать данные в нескольких таблицах и уменьшить избыточность. Это означает, что в базе данных может быть несколько таблиц, связанных друг с другом.
Предотвращение вставки некорректных данных. Если две таблицы в базе данных связаны через поле (атрибут), использование FOREIGN KEY
гарантирует, что в это поле не будут вставлены неверные данные. Это помогает устранить ошибки на уровне базы данных.
FOREIGN KEY с оператором ALTER TABLE
Можно добавить ограничение FOREIGN KEY
к существующей таблице с помощью оператора ALTER TABLE. Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
CREATE TABLE Customers ( id INT, first_name VARCHAR(40), last_name VARCHAR(40), age INT, country VARCHAR(10), CONSTRAINT CustomersPK PRIMARY KEY (id) ); CREATE TABLE Orders ( order_id INT, item VARCHAR(40), amount INT, customer_id INT, CONSTRAINT OrdersPK PRIMARY KEY (order_id) ); -- Добавляем внешний ключ к полю customer_id. -- Внешний ключ ссылается на поле id таблицы Customers ALTER TABLE Orders ADD FOREIGN KEY (customer_id) REFERENCES Customers(id); |
Несколько внешних ключей в таблице
Таблица может иметь несколько внешних ключей. Предположим, нам нужно записать все транзакции, где каждый пользователь одновременно является покупателем и продавцом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
-- Эта таблица не имеет внешнего ключа CREATE TABLE Users ( id INT, first_name VARCHAR(40), last_name VARCHAR(40), age INT, country VARCHAR(10), CONSTRAINT CustomersPK PRIMARY KEY (id) ); -- Добавляем внешний ключ к полям buyer и seller. -- Внешний ключ ссылается на поле id таблицы Users CREATE TABLE Transactions ( transaction_id INT, amount INT, seller INT REFERENCES Users(id), buyer INT REFERENCES Users(id), CONSTRAINT TransactionsPK PRIMARY KEY (transaction_id) ); |
Здесь мы создаем два внешних ключа (buyer и seller) в таблице Transactions.