Внешние ключи и схема базы данных
Содержание курса
Три типа связей: один-к-одному, один-ко-многим, многие-ко-многим
Тип связи определяется одним вопросом: сколько строк одной таблицы может соответствовать одной строке другой — и в каком направлении?
Один-ко-многим — самый частый случай. Одному клиенту может принадлежать много заказов, но каждый заказ относится ровно к одному клиенту. Внешний ключ всегда размещается на стороне «многих»: orders.customer_id живёт в таблице заказов, а не в таблице клиентов. Если customer_id объявлен NOT NULL, у каждого заказа обязательно есть клиент; без NOT NULL заказ теоретически может быть «ничьим».
Один-к-одному — частный случай один-ко-многим с дополнительным ограничением. Представим, что employees хранит основные данные сотрудника, а employee_details — расширенный профиль. Внешний ключ employee_details.employee_id → employees.employee_id сам по себе допускает несколько профилей на одного сотрудника. Чтобы этого не было, столбец внешнего ключа должен быть объявлен с UNIQUE. Тогда одна строка employees может иметь не более одной строки employee_details — и наоборот. Именно UNIQUE превращает связь из один-ко-многим в один-к-одному.
Многие-ко-многим нельзя выразить одним внешним ключом ни в одной из двух таблиц. Один заказ содержит несколько товаров, и один товар входит в несколько заказов. Если добавить product_id прямо в orders, можно хранить только один товар на заказ. Если добавить order_id в products — только один заказ на товар. Оба варианта неправильны.
Решение — таблица-связка: отдельная таблица order_items, где каждая строка хранит пару (order_id, product_id). Оба столбца — внешние ключи к своим таблицам. Нужно добавить товар в заказ — добавляем строку в order_items. Один заказ с тремя товарами даёт три строки; один товар в десяти заказах даёт десять строк. Таблица-связка — единственный реляционный способ реализовать многие-ко-многим.
