Что такое Foreign Key (внешний ключ) в базах данных?

Ответ

Foreign Key (FK, внешний ключ) — это ограничение в реляционных базах данных, которое обеспечивает ссылочную целостность между таблицами. FK указывает, что значения в столбце (или группе столбцов) одной таблицы должны соответствовать значениям первичного ключа (Primary Key) другой таблицы.

Пример создания в SQL:

-- Таблица авторов (родительская)
CREATE TABLE authors (
    id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

-- Таблица книг (дочерняя) с внешним ключом
CREATE TABLE books (
    id INT PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    author_id INT,
    FOREIGN KEY (author_id) REFERENCES authors(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);

Действия при удалении/обновлении (ON DELETE/UPDATE):

  • CASCADE — удалить/обновить связанные записи
  • RESTRICT / NO ACTION — запретить операцию при наличии связей
  • SET NULL — установить NULL в FK-столбце
  • SET DEFAULT — установить значение по умолчанию

Практическое значение:

  1. Целостность данных — предотвращает "сиротские" записи (книги без автора)
  2. Связи между сущностями — реализует отношения "один-ко-многим"
  3. Оптимизация запросов — индексы на FK улучшают JOIN-операции

В SQL-запросах FK неявно используется в JOIN:

SELECT b.title, a.name
FROM books b
JOIN authors a ON b.author_id = a.id;

Ответ 18+ 🔞

А, внешние ключи! Ну это ж классика, ёпта. Сидишь такой, проектируешь свою базу, а тут бац — и понимаешь, что одни таблицы с другими наглухо переплетены, как пьяные родственники на свадьбе. И если эту связь не оформить по-человечески, то потом будет пиздец рулю.

Вот смотри. Есть у тебя таблица authors — ну, авторы, ясное дело. У каждого свой id, как паспорт. А есть таблица books — книги. И у каждой книги должен быть автор, верно? А иначе получится манда с ушами: книга есть, а кто её написал — хуй знает. Вот чтобы такого не было, и придумали внешний ключ, или Foreign Key (FK).

По сути, это такой строгий договор между таблицами. Ты говоришь базе: «Слушай сюда, ёб твою мать. Значение в столбце author_id таблицы books — это не просто цифра. Это священная ссылка на id в таблице authors. Так что если какого-то автора нет в authors, то и вписывать его id в книги — ни хуя себе».

Вот как это выглядит в коде, если делать всё по-взрослому:

-- Таблица авторов (родительская)
CREATE TABLE authors (
    id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

-- Таблица книг (дочерняя) с внешним ключом
CREATE TABLE books (
    id INT PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    author_id INT,
    FOREIGN KEY (author_id) REFERENCES authors(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);

Видишь эту магическую строчку FOREIGN KEY (author_id) REFERENCES authors(id)? Это и есть договор. А дальше идёт самое интересное — правила поведения на случай драки.

Эти ON DELETE/UPDATE — они как раз и определяют, что делать, если кто-то в родительской таблице решит навести шороху.

  • CASCADE — самый радикальный вариант. Удалили автора — автоматом хуй с горы — все его книги тоже полетели в корзину. Обновили id автора — во всех книгах author_id тоже поменяется. Мощно, но иногда слишком.
  • RESTRICT / NO ACTION — позиция принципиального бухгалтера. «Пока на этого автора есть ссылки из книг, какого хуя ты его удаляешь? Не дам!» Операция просто не выполнится.
  • SET NULL — более мягкий вариант. Автора удалили? Ладно, в поле author_id у его книг просто встанет NULL. Книги-то останутся, но автор станет «Неизвестен». Типа, сам от себя охуел.
  • SET DEFAULT — похоже на предыдущее, но вместо NULL подставится какое-то значение по умолчанию, которое ты заранее определил.

А нахуя это всё нужно, спросишь? Да овердохуища причин!

  1. Целостность, блядь. Это главное. База не даст тебе записать в books левый author_id, которого нет в authors. Никаких «книг-сирот». Данные будут чистыми, а сон — спокойным.
  2. Очевидные связи. Глядя на схему, сразу видно, что книги зависят от авторов. Не нужно гадать, э, бошка, думай, как это всё связано.
  3. Скорость. Умные СУБД обычно автоматом создают индекс для внешнего ключа. А когда ты потом делаешь JOIN, чтобы выбрать книги с именами авторов, этот индекс ебет копать и всё летает.

Собственно, JOIN — это и есть момент, когда внешний ключ выходит на сцену:

SELECT b.title, a.name
FROM books b
JOIN authors a ON b.author_id = a.id; -- Вот он, наш герой, в условии связи!

Короче, внешний ключ — это не просто прихоть. Это фундаментальная штука, которая превращает кучу разрозненных таблиц в стройную, логичную систему. Без него твоя база — просто набор данных, в котором доверия ебать ноль. А с ним — уже серьёзная, взрослая архитектура.