Модуль 17

Звʼязки: One-to-Many

Ось твій урок у стилі CS50. Вмикай уяву, ми починаємо!


🎓 УРОК CS50: Архітектура даних. Звʼязки One-to-Many (Один-до-Багатьох)

Привіт, світ! 👋

Сьогодні ми не просто пишемо код. Ми стаємо архітекторами. Ми будемо будувати структуру, яка лежить в основі Facebook, Amazon, Netflix і навіть маленького блогу вашого друга.

Тема сьогоднішнього дня — One-to-Many ("Один-до-Багатьох").


1. 🔥 Вступ: Чому це болить?

Уявіть, що ви працюєте в Excel (так, я знаю, це боляче, але уявіть). Ви ведете облік замовлень в інтернет-магазині.

У вас є клієнт: Остап Бендер. Сьогодні він купив шарф. Завтра він купує стілець. Післязавтра — квиток до Ріо.

Як ви це запишете в одну таблицю?

ID Замовлення Клієнт Телефон Адреса Товар
1 Остап Бендер +38099... Одеса, Дерибасівська Шарф
2 Остап Бендер +38099... Одеса, Дерибасівська Стілець
3 Остап Бендер +38099... Одеса, Дерибасівська Квиток

Питання до вас: Що тут не так? Що вас дратує в цій таблиці?

Правильно! Дублювання. Ми тричі скопіювали ім'я, телефон і адресу Остапа. А що, як Остап переїде до Ріо? Вам доведеться шукати всі його старі замовлення і міняти адресу в кожному рядку. Якщо ви пропустите хоч один — ваші дані перетворяться на сміття.

Це називається аномалією даних. І в програмуванні ми цього ненавидимо.

Рішення? Розділити це на дві сутності. Окремо — Остап (один раз). Окремо — його покупки (багато разів). Це і є зв'язок Один-до-Багатьох.


2. 🧠 Теоретична база: Як це працює «під капотом»

Давайте розберемо це на атоми.

One-to-Many (1:N) — це тип зв'язку, де один запис з таблиці A може посилатися на багато записів у таблиці B. Але запис із таблиці B посилається тільки на один запис з таблиці A.

Аналогія з життя 🏙

Уявіть Маму і її Дітей. * У однієї Мами може бути багато Дітей (One-to-Many). * Але у кожної Дитини (біологічно) лише одна Мама.

Як ми пов’язуємо їх у базі даних?

Ми не можемо провести фізичну мотузку між таблицями. Нам потрібен цифровий "гачок".

Цей гачок називається Foreign Key (Зовнішній ключ).

🔴 Головне правило (запам'ятайте це назавжди!):

У зв'язку "Один-до-Багатьох" посилання (Foreign Key) ЗАВЖДИ зберігається на стороні "Багатьох".

Чому? Уявіть паспорт мами. Чи можемо ми вписати туди імена всіх її майбутніх дітей? Ні, місця не вистачить, і ми не знаємо, скільки їх буде. Але у свідоцтві про народження кожної дитини є графа "Мати". Це і є Foreign Key.


3. 🧪 Приклади: Від простого до реального

Давайте спроектуємо це в SQL (мові баз даних).

Приклад 1: Автори та Книги 📚

Один автор написав багато книг. Одна книга має одного автора (для спрощення).

Таблиця 1: authors (Батьки) | id | name | | :--- | :--- | | 1 | Тарас Шевченко | | 2 | Леся Українка |

Таблиця 2: books (Діти)Питання: Де ми поставимо зв'язок? Правильно, у книгах. Ми додаємо колонку author_id.

id title author_id (Foreign Key)
101 Кобзар 1
102 Катерина 1
103 Лісова пісня 2

Як це читає комп'ютер: 1. Він бачить книгу "Кобзар". 2. Бачить author_id = 1. 3. Йде в таблицю authors, шукає id = 1. Ага! Це Тарас Шевченко.


Приклад 2: Реальний світ (Instagram) 📸

У нас є Користувачі (users) та їхні Пости (posts).

-- Створюємо батька (Користувач)
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50)
);

-- Створюємо дітей (Пости)
CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    image_url VARCHAR(255),
    caption TEXT,

    -- ОСЬ ВОНО! Зв'язок:
    user_id INTEGER REFERENCES users(id)
);

Дивіться, як просто. Ми просто кажемо таблиці posts: "Гей, у тебе є колонка user_id, і вона повинна вказувати на реальний id з таблиці users".


4. 🛠 Практична частина

Час забруднити руки кодом! 💻

Завдання 1: Повторення На папері або в редакторі спроектуй дві таблиці для ситуації: "Вчитель" і "Учні". (Припускаємо, що у класного керівника багато учнів, але у учня один класний керівник). Де буде знаходитись teacher_id?

Завдання 2: Музичний плеєр У вас є сутності: Artist (Виконавець) та Song (Пісня). Напишіть структуру даних (які колонки в якій таблиці), щоб зв'язати їх.

Завдання 3: Виправляємо помилку новачка Студент написав таку структуру для Режисерів та Фільмів:

  • Таблиця directors: id, name, movie_id
  • Таблиця movies: id, title

Чому це погано? Що станеться, якщо Крістофер Нолан зніме другий фільм? Виправте це.

Завдання 4: Міні-кейс "Лікарня" Є Doctor (Лікар) і Patient (Пацієнт). Лікар веде багатьох пацієнтів. Як виглядатиме запис пацієнта "Іван", якого лікує "Доктор Хаус" (id=5)?

Завдання 5: А що, якщо... Що станеться з таблицею books (з першого прикладу), якщо ми видалимо Тараса Шевченка з таблиці authors? (Підказка: база даних почне панікувати, бо книги стануть "сиротами". Це називається цілісністю даних).


5. 💡 Мислення як у розробника

Як думає Senior Developer, коли бачить нову задачу?

  1. "Who owns whom?" (Хто ким володіє?) Перше питання, яке ви маєте собі поставити. Якщо "Кошик" належить "Користувачу", то user_id йде в таблицю "Кошик".

  2. Уникайте списків через кому. Помилка новачка: Зробити таблицю authors і додати колонку books_list, записавши туди: "Кобзар, Катерина, Сон". Чому ні? Спробуйте потім знайти всі книги, назва яких починається на "К". Вам доведеться парсити текст. Це повільно і жахливо. Завжди використовуйте окремі рядки і Foreign Keys.

  3. Думайте про масштабування. Сьогодні у користувача 1 пост, завтра — 10 000. Структура One-to-Many ідеально це витримує, бо таблиця users не росте в ширину, росте тільки таблиця posts у довжину (а бази даних обожнюють рости в довжину).


6. 🧩 Підсумок

Отже, що ми маємо в сухому залишку:

  1. One-to-Many — це коли один об'єкт володіє багатьма іншими.
  2. Ми використовуємо Foreign Key (Зовнішній ключ), щоб їх з'єднати.
  3. Ключ ЗАВЖДИ лежить у таблиці "Багатьох" (у дитини, у книги, у замовлення).

Що ви тепер вмієте? Ви можете взяти хаотичний набір даних і розкласти його по поличках так, як це роблять у професійних системах. Ви позбулися дублювання! 🎉

🚀 Тизер наступного уроку: А що робити, якщо Один студент ходить на Багато курсів, але й на Одному курсі навчається Багато студентів? Зв'язок "Багато-до-Багатьох" (Many-to-Many) — це вже вищий пілотаж, і там нам знадобиться третя секретна таблиця.

Але це вже зовсім інша історія. Це був CS50. До зустрічі!