Ось урок, створений у стилі 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. 🧠 Теоретична база: Розділяй і володарюй
Щоб вирішити проблему дублювання, ми використовуємо Реляційні Бази Даних. Головна ідея — розбити дані на логічні частини (таблиці) і пов'язати їх.
Ключові поняття (без нудних лекцій):
- Таблиці (Entities): Замість однієї великої, ми робимо дві маленькі:
users(користувачі) таorders(замовлення). - Primary Key (PK, Первинний ключ): Це унікальний ID. Як номер паспорта або ІПН. У кожного користувача має бути свій унікальний
id. - 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. 💡 Мислення як у розробника
Коли ви починаєте працювати з кількома таблицями, легко заплутатися. Ось як думають профі:
-
"Чиї це дані?" Перш ніж писати код, подумайте про відношення "Один-до-Багатьох". Один автор — багато книг. Значить, посилання (
author_id) завжди зберігається там, де "багато" (у книгах). Порада: Зовнішній ключ — це як етикетка на товарі "Зроблено компанією X". -
Небезпека "Двозначності" (Ambiguity) Якщо в обох таблицях є колонка
name(назва книги і ім'я автора), і ви напишетеSELECT name..., база даних видасть помилку: "Яке name ти маєш на увазі?!". Рішення: Завжди уточнюйте:authors.name,books.title. Або використовуйте псевдоніми (aliases):FROM authors AS a JOIN books AS b ON a.id = b.author_id. -
Синдром "Загублених даних" Новачки часто бояться, що дані зникнуть при
JOIN. Пам'ятайте:SELECTнічого не видаляє і не змінює. Це лише "ліхтарик", яким ми світимо на дані під певним кутом.
6. 🧩 Підсумок
Сьогодні ми зробили величезний крок від простих списків до справжньої архітектури даних.
Що ви тепер вмієте:
* Розумієте, навіщо розбивати дані на таблиці (нормалізація).
* Знаєте, що таке Primary Key (паспорт) і Foreign Key (посилання).
* Вмієте використовувати JOIN, щоб збирати розрізнені дані в єдину картину.
Тизер наступного уроку: А що, як у нас є ситуація "Багато-до-Багатьох"? Наприклад, один Студент відвідує багато Курсів, а на одному Курсі — багато Студентів. Куди ставити ID? У студентів? У курси? Відповідь вас здивує: нам знадобиться... третя таблиця. Але про це — наступного разу.
Це був CS50. Побачимось!