Модуль 9

Working with Multiple Tables

Ось урок, створений у стилі CS50: енергійний, з живими прикладами та акцентом на "чому", а не тільки "як".


🎓 CS50: Робота з кількома таблицями (SQL & Relational Databases)

Привіт, друзі! Це CS50, і сьогодні ми переходимо на новий рівень роботи з даними.

1. 🔥 Вступ: Чому одна таблиця — це зло?

Уявіть, що ви відкриваєте Excel або Google Sheets, щоб вести облік замовлень для вашого нового стартапу — піцерії. Ви створюєте таблицю:

Замовлення Клієнт Телефон Адреса Піца Ціна
1 Олексій 099-111 вул. Шевченка, 10 Пепероні 200
2 Марія 097-222 пр. Науки, 5 Гавайська 210
3 Олексій 099-111 вул. Шевченка, 10 4 Сири 250

Здається, все чудово, правда? Але подивіться уважніше на рядки 1 і 3. Олексій замовив піцу двічі.

А тепер уявіть ситуацію: 1. Олексій переїхав на іншу вулицю. 2. Вам потрібно оновити його адресу. 3. Що ви робите? Ви шукаєте всі рядки з Олексієм і змінюєте адресу в кожному з них.

А якщо у вас 10,000 замовлень, і Олексій зробив 50 з них? А якщо ви помилилися в одній літері в одному рядку? У вас з'являється "Олексій" і "Олескій". Система думає, що це дві різні людини. Хаос.

Чому без цього не обійтись? У реальному світі дані дублюються. Якщо ми зберігаємо все в одній "супер-таблиці", ми витрачаємо пам’ять і створюємо пекло для підтримки актуальності даних.

Аналогія: Уявіть свою шафу. Ви ж не купуєте окрему шкарпетку для кожних кросівок, правда? У вас є одні ноги, і ви змінюєте взуття. Так само і тут: у нас є один клієнт, який може робити багато замовлень. Нам потрібно відокремити "Клієнтів" від "Замовлень".


2. 🧠 Теоретична база: Розділяй і володарюй

Щоб вирішити проблему дублювання, ми використовуємо Реляційні Бази Даних. Головна ідея — розбити дані на логічні частини (таблиці) і пов'язати їх.

Ключові поняття (без нудних лекцій):

  1. Таблиці (Entities): Замість однієї великої, ми робимо дві маленькі: users (користувачі) та orders (замовлення).
  2. Primary Key (PK, Первинний ключ): Це унікальний ID. Як номер паспорта або ІПН. У кожного користувача має бути свій унікальний id.
  3. Foreign Key (FK, Зовнішній ключ): Це "місток". У таблиці замовлень ми не пишемо ім'я "Олексій". Ми пишемо: "Замовлення зробив клієнт з id = 1".

Як це працює "під капотом"?

Комп'ютеру набагато легше порівнювати числа (1 = 1), ніж рядки тексту ("Олексій" = "Олексій"). Коли ви хочете дізнатися, хто зробив замовлення, база даних бере число з orders, біжить у таблицю users, знаходить цей номер і каже: "Ага! Це Олексій!"

Запам’ятайте: Ми зберігаємо дані в різних місцях, щоб не дублювати їх, але "зшиваємо" їх разом у момент запиту. Це називається JOIN.


3. 🧪 Приклади: Магія JOIN

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

Вхідні дані

У нас є дві таблиці.

Таблиця users: | id | name | | :--- | :--- | | 1 | Олексій | | 2 | Марія |

Таблиця orders: | id | user_id | product | | :--- | :--- | :--- | | 101 | 1 | Пепероні | | 102 | 2 | Гавайська | | 103 | 1 | 4 Сири |

Зауважте: у таблиці orders немає імен, тільки user_id.

Приклад 1: Просте з'єднання (INNER JOIN)

Ми хочемо отримати список: Хто що купив.

Запитання до вас: Як пояснити базі даних, що user_id у замовленнях — це те саме, що id у користувачів?

Код:

SELECT users.name, orders.product
FROM users
JOIN orders ON users.id = orders.user_id;

Що тут відбувається: 1. FROM users: Беремо таблицю користувачів. 2. JOIN orders: Приклеюємо до неї таблицю замовлень. 3. ON users.id = orders.user_id: Найважливіший момент! Ми кажемо: "З'єднай рядки тільки там, де ID збігаються".

Результат: | name | product | | :--- | :--- | | Олексій | Пепероні | | Марія | Гавайська | | Олексій | 4 Сири |

Бачите? Олексій з'явився двічі, бо у нього два замовлення. База даних сама розмножила його ім'я для звіту, але в пам'яті воно зберігається лише раз!


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

Час "забруднити руки" кодом. Уявіть, що ви працюєте з базою даних бібліотеки.

Таблиці: * books (id, title, author_id) * authors (id, name)

Завдання 1: Віднови справедливість

Напиши запит, який покаже назву книги (title) та ім'я автора (name). (Підказка: використовуй JOIN та ON).

Завдання 2: А що, якщо...?

Уяви, що у нас є автор, який ще не написав жодної книги. Якщо ти використаєш звичайний JOIN (він же INNER JOIN), чи з'явиться цей автор у результаті? (Спробуй здогадатися, а потім перевір. Спойлер: Ні, бо немає "пари" в таблиці книг).

Завдання 3: Виправити помилку

Студент написав такий код:

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

Чому цей код поверне повну нісенітницю? Що не так з умовою після ON? (Підказка: ми з'єднуємо ID автора з ID книги, чи ID автора з посиланням на автора?)

Завдання 4: Міні-кейс

Ти розробляєш систему для блогу. Є таблиця posts (статті) і comments (коментарі). Один пост може мати багато коментарів. Яке поле (post_id) і в яку таблицю ти додаси, щоб зв'язати їх?


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

Коли ви починаєте працювати з кількома таблицями, легко заплутатися. Ось як думають профі:

  1. "Чиї це дані?" Перш ніж писати код, подумайте про відношення "Один-до-Багатьох". Один автор — багато книг. Значить, посилання (author_id) завжди зберігається там, де "багато" (у книгах). Порада: Зовнішній ключ — це як етикетка на товарі "Зроблено компанією X".

  2. Небезпека "Двозначності" (Ambiguity) Якщо в обох таблицях є колонка name (назва книги і ім'я автора), і ви напишете SELECT name..., база даних видасть помилку: "Яке name ти маєш на увазі?!". Рішення: Завжди уточнюйте: authors.name, books.title. Або використовуйте псевдоніми (aliases): FROM authors AS a JOIN books AS b ON a.id = b.author_id.

  3. Синдром "Загублених даних" Новачки часто бояться, що дані зникнуть при JOIN. Пам'ятайте: SELECT нічого не видаляє і не змінює. Це лише "ліхтарик", яким ми світимо на дані під певним кутом.


6. 🧩 Підсумок

Сьогодні ми зробили величезний крок від простих списків до справжньої архітектури даних.

Що ви тепер вмієте: * Розумієте, навіщо розбивати дані на таблиці (нормалізація). * Знаєте, що таке Primary Key (паспорт) і Foreign Key (посилання). * Вмієте використовувати JOIN, щоб збирати розрізнені дані в єдину картину.

Тизер наступного уроку: А що, як у нас є ситуація "Багато-до-Багатьох"? Наприклад, один Студент відвідує багато Курсів, а на одному Курсі — багато Студентів. Куди ставити ID? У студентів? У курси? Відповідь вас здивує: нам знадобиться... третя таблиця. Але про це — наступного разу.

Це був CS50. Побачимось!