Моделирование связей: один-ко-многим
Учимся разносить данные по связанным таблицам вместо одной большой.
Связь один-ко-многим — это когда одной строке в первой таблице соответствует много строк во второй (один клиент — много заказов).
Почему не одна большая таблица
Заманчиво хранить всё в одной таблице: имя клиента, его город и тут же каждый его заказ. Но тогда имя и город клиента повторяются в каждой строке заказа. Это плохо: данные раздуваются, а при смене города придётся править десятки строк и легко ошибиться. Решение — разнести данные по таблицам и связать их ключами.
Две таблицы и связь
Сделаем таблицу клиентов и таблицу заказов. У каждого заказа есть customer_id — ссылка на клиента. Один клиент может иметь много заказов: это и есть связь один-ко-многим, а внешний ключ ставится на стороне «многих» (в заказах).
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name TEXT
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER, -- ссылка на customers.id
amount INTEGER
);
INSERT INTO customers (id, name) VALUES (1, 'Аня'), (2, 'Борис'), (3, 'Вера');
INSERT INTO orders (customer_id, amount) VALUES
(1, 500), (1, 1200), (2, 800);
SELECT * FROM orders;
Вывод:
1|1|500 2|1|1200 3|2|800
Видно, что у Ани (id = 1) два заказа, у Бориса (id = 2) один, а у Веры (id = 3) пока ни одного. Имя клиента нигде не дублируется — оно хранится один раз в таблице customers.
Как связать данные обратно
Сейчас в заказах виден только числовой customer_id, а не имя. Чтобы показать имя клиента рядом с заказом, таблицы нужно «соединить» по этому ключу. Это делает оператор JOIN — ему посвящён следующий урок. Связь, которую мы спроектировали, — фундамент: дальше всё построено на ней.
Другие виды связей (коротко)
- Один-ко-многим — самый частый: клиент → заказы, автор → книги, категория → товары. Ключ на стороне «многих».
- Один-к-одному — редкая: например, пользователь и его расширенный профиль в отдельной таблице.
- Многие-ко-многим — например, студенты и курсы: один студент на многих курсах, на курсе много студентов. Реализуется через третью, связующую таблицу с двумя внешними ключами.
Итог
- Данные разносят по таблицам, чтобы не дублировать и не рассогласовывать их.
- В связи один-ко-многим внешний ключ ставится на стороне «многих» (в заказах —
customer_id). - Связь многие-ко-многим реализуют через отдельную связующую таблицу.