Модуль 19

Designing a Real Database Schema

Ось готовий урок, згенерований за твоїм майстер-промптом.


🎓 CS50 Style: Проєктування Реальної Бази Даних (Schema Design)

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

Сьогоднішня тема — Designing a Real Database Schema (Проєктування схеми бази даних).


1. 🔥 Вступ: Чому Excel — це не База Даних?

Уявіть, що ви вирішили створити власний аналог Uber або Instagram. У вас є геніальна ідея, ви знаєте, як написати код для кнопок... Але де ви будете зберігати інформацію?

Давайте почнемо з найпростішого варіанту. Уявіть, що ви відкрили Google Sheets або Excel. Ви пишете в один рядок: Ім'я користувача, Пароль, Пошта, Історія поїздок, Номер картки, Марка машини водія.

Все йде чудово, поки... * Один користувач не робить 50 поїздок. Що ви робите? Дублюєте його ім'я та пошту в 50 рядках? * Користувач змінює прізвище. Ви тепер шукаєте всі 50 рядків і правите їх вручну? А якщо пропустите один? * А як записати, що в одній машині їхало троє пасажирів? Писати їх через кому в одній клітинці?

Риторичне запитання: Чи зручно буде вашому коду шукати "всіх водіїв на Toyota", якщо дані розкидані як попало?

Аналогія: Зберігати все в одній таблиці — це як скидати весь свій одяг (шкарпетки, куртки, білизну, взуття) у одну велетенську коробку. Знайти там пару шкарпеток зранку — це пекло. База даних — це шафа-органайзер. Окрема шухляда для шкарпеток, вішаки для сорочок, полиця для взуття. Все має своє місце і свій "ярлик".


2. 🧠 Теоретична база: Думаємо сутностями

Щоб навести лад, нам треба перестати думати "рядками" і почати думати Сутностями (Entities) та Зв'язками (Relationships).

🔑 Ключові поняття (без води):

  1. Сутність (Table): Це іменник. Користувач, Товар, Замовлення. Кожна сутність — це окрема таблиця.
  2. Атрибут (Column): Це прикметник або деталь. Колір, Ціна, Ім'я, Дата.
  3. Первинний ключ (Primary Key / PK): Унікальний паспорт сутності. Зазвичай це просто число ID (1, 2, 3...). Навіть якщо є два "Тараси Шевченки", у них будуть різні ID.
  4. Зовнішній ключ (Foreign Key / FK): Це "посилання" на іншу таблицю. Замість того, щоб писати "Тарас Шевченко" в замовленні, ми пишемо user_id: 42.

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

База даних не читає текст так, як ми. Їй байдуже на слово "iPhone". Їй важливо, що це запис №505 у таблиці Products. Коли ми використовуємо ID замість тексту, ми економимо місце і робимо пошук миттєвим.

Що треба запам’ятати залізно: Ніколи не зберігайте одну й ту саму інформацію (наприклад, адресу клієнта) у двох різних місцях. Якщо адреса зміниться, ви отримаєте розсинхронізацію даних. Це називається аномалією оновлення.


3. 🧪 Приклади: Будуємо магазин (E-commerce)

Давайте спроєктуємо базу для інтернет-магазину.

Спроба №1 (Погана, наївна)

Одна таблиця Orders: | id | customer_name | customer_email | product_name | product_price | order_date | |----|---|---|---|---|---| | 1 | Olena | olena@gmail.com | Laptop | 1000 | 2023-10-01 | | 2 | Olena | olena@gmail.com | Mouse | 20 | 2023-10-02 |

Що тут не так? Дивіться на Олену. Ми двічі записали її пошту. Якщо вона змінить пошту, нам гаплик.

Спроба №2 (Розділяємо сутності 1:N)

Створимо дві таблиці: Users та Orders.

Table: Users | id (PK) | name | email | |---|---|---| | 1 | Olena | olena@gmail.com | | 2 | Ihor | ihor@test.com |

Table: Orders | id (PK) | user_id (FK) | total_price | date | |---|---|---|---| | 101 | 1 | 1200 | 2023-10-01 | | 102 | 1 | 50 | 2023-10-02 |

Бачите user_id: 1? Це і є зв'язок! Це зв'язок Один-до-Багатьох (One-to-Many): Один юзер може мати багато замовлень, але одне замовлення належить одному юзеру.

Спроба №3 (Складна: Багато-до-Багатьох / N:M)

А де ж товари? В одному замовленні може бути багато товарів. І один товар (наприклад, iPhone 15) може бути у багатьох різних замовленнях різних людей.

Це зв'язок Багато-до-Багатьох. Як це реалізувати? Ми не можемо записати список ID товарів в одну клітинку через кому (це гріх у світі баз даних!).

Нам потрібна Проміжна таблиця (Join Table). Назвемо її Order_Items.

Table: Order_Items | order_id (FK) | product_id (FK) | quantity | |---|---|---| | 101 | 55 (Laptop) | 1 | | 101 | 56 (Mouse) | 1 | | 102 | 56 (Mouse) | 2 |

Результат: Ми зв'язали замовлення і товари, не дублюючи інформацію про самі товари.


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

Час забруднити руки! Візьміть аркуш паперу або відкрийте текстовий редактор.

🔹 Завдання 1: "Блог"

Спроєктуйте схему для простого блогу. Потрібно зберігати: Авторів, Статті та Коментарі. Підказка: У статті один автор, але багато коментарів. Коментар належить одній статті і одному автору. Напишіть: Які будуть таблиці і які там будуть поля _id.

🔹 Завдання 2: "Лікарня"

У вас є Пацієнти і Лікарі. Один пацієнт може ходити до різних лікарів. Один лікар приймає багатьох пацієнтів. Як ви це зв'яжете? (Намалюйте проміжну таблицю).

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

У вас є таблиця Students. Там є колонка subjects, де записано: "Math, History, Physics". Чому це погано і як це переробити у нормальну структуру?

🔹 Міні-кейс: "Служба доставки"

Потрібно додати можливість користувачу мати декілька адрес доставки (Дім, Робота, Батьки). Чи треба додавати колонки address1, address2 в таблицю Users? Чи є кращий шлях?


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

Як відрізнити новачка від профі ще на етапі малювання табличок?

  1. Помилка новачка: Зберігати списки в рядку.

    • Bad: Tags: "funny, cats, video"
    • Good: Окрема таблиця Tags і проміжна таблиця Post_Tags. Чому? Бо потім менеджер скаже: "Покажи мені всі пости з тегом 'cats'", і з першим варіантом ви будете страждати, розбираючи текст.
  2. Правило профі: "Думай запитами". Перед тим як створити таблицю, уявіть SQL-запит, який ви будете писати.

    • "Мені часто треба буде шукати користувачів за номером телефону?" -> Значить, номер телефону має бути окремою колонкою, можливо, навіть проіндексованою, а не частиною великого тексту.
  3. Атомарність: Не пишіть в одне поле Address: "Київ, Хрещатик 1, кв 5". Краще розбити: City, Street, Building. Чому? Бо завтра вас попросять: "Скільки у нас клієнтів з Києва?". З розбитою структурою це робиться за секунду.


6. 🧩 Підсумок

Отже, що ми сьогодні зробили? Ми перетворили хаос "великої таблиці Excel" на елегантну структуру реляційної бази даних.

  1. Ви зрозуміли, що дані треба ділити на логічні сутності (таблиці).
  2. Ви навчилися з'єднувати їх "ниточками" — Foreign Keys.
  3. Ви знаєте, як вирішити проблему Many-to-Many за допомогою проміжної таблиці.

Що ви тепер вмієте: Ви можете взяти будь-яку ідею (додаток для знайомств, трекер звичок, складський облік) і намалювати його "скелет" на папері.

Тизер: Тепер у нас є ідеальна структура порожніх таблиць. Але як нам покласти туди дані? І найголовніше — як їх звідти дістати, з’єднавши три таблиці в один звіт? На наступному уроці ми познайомимось із магією мови SQL і командою JOIN. Це буде... legendary.

А поки що — це був CS50.