Ось готовий урок, створений спеціально за твоїм запитом, у стилі CS50 — енергійно, зрозуміло і з фокусом на те, як це працює насправді.
🎓 Урок: Поля моделей та звʼязки між таблицями
(Або: Чому Excel — це не база даних, і як навести лад у хаосі)
1. 🔥 Вступ: Проблема дублювання (або "Ефект стікера")
Уявіть, що ви керуєте невеликою бібліотекою. Спочатку у вас всього 10 книг. Ви берете звичайний блокнот (або Excel-таблицю) і пишете:
| Назва книги | Автор | Жанр |
|---|---|---|
| Кобзар | Тарас Шевченко | Поезія |
| Гайдамаки | Т.Г. Шевченко | Поема |
| Катерина | Шевченко Тарас | Класика |
Все виглядає непогано, правда? Але подивіться уважніше.
Запитання до вас: Скільки унікальних авторів у цій таблиці? Для комп’ютера — три. 1. "Тарас Шевченко" 2. "Т.Г. Шевченко" 3. "Шевченко Тарас"
Коли ви захочете знайти всі книги Шевченка, комп’ютер скаже: "Якого саме? Цього, того чи ось цього?". Це катастрофа.
А що, як Шевченко вирішить змінити псевдонім? Вам доведеться бігати по всьому блокноту і виправляти це в тисячі рядків. Це неефективно, повільно і небезпечно (можна щось пропустити).
Ось навіщо нам потрібні Моделі та Зв’язки. Ми хочемо написати ім’я автора один раз і просто посилатися на нього. Як у бібліотечному каталозі: картка автора окремо, картка книги окремо.
Сьогодні ми перетворимо хаос на структуру.
2. 🧠 Теоретична база: Що "під капотом"?
У світі розробки (особливо веб-розробки, як у Django чи Laravel) ми використовуємо ORM. Не лякайтеся абревіатури. Це просто "перекладач" з мови об'єктів (Python, PHP, JS) на мову бази даних (SQL).
🧱 Поля (Fields) — це ваші контейнери
Коли ми створюємо таблицю, ми повинні суворо сказати базі даних, що саме ми туди кладемо.
- CharField (Рядок): Для коротких текстів (Ім'я, Назва). Уявіть це як стікер — місця мало, пишемо швидко.
- TextField (Текст): Для великих статей. Це вже цілий зошит.
- IntegerField (Число): Тільки цілі числа (Кількість сторінок). Ніяких "3.5 сторінки".
- DateField (Дата): Календарик.
Інтуїтивно: База даних — це педант. Якщо ви скажете, що поле для дати, вона ніколи не дозволить записати туди слово "вчора". І це рятує нас від помилок!
🔗 Зв’язки (Relationships) — магія посилань
Тут починається найцікавіше. Є три типи стосунків між даними:
- Один-до-Багатьох (One-to-Many):
- Приклад: Один Автор — Багато Книг.
- Як це працює: У таблиці "Книги" ми не пишемо ім'я автора. Ми пишемо його ID (унікальний номер).
- Багато-до-Багатьох (Many-to-Many):
- Приклад: Піца та Інгредієнти. Одна піца має багато інгредієнтів. Один інгредієнт (сир) використовується в багатьох піцах.
- Як це працює: Створюється третя, прихована "таблиця-посередник", де записано: "Піца №1 дружить з Інгредієнтом №5".
- Один-до-Одного (One-to-One):
- Приклад: Громадянин і Паспорт. У одного громадянина — один дійсний паспорт.
- Навіщо: Щоб не пхати все в одну гігантську таблицю.
3. 🧪 Приклади (Код, який говорить)
Уявімо, що ми пишемо код для блогу (класика CS50!). Використаємо псевдокод, схожий на Python/Django.
Приклад 1: Проста модель (Без зв'язків)
Спершу нам потрібен користувач.
class User(Model):
name = CharField(max_length=100) # Ім'я, обмежене довжиною
email = EmailField() # Перевіряє наявність @
is_active = BooleanField() # Так/Ні
Що очікуємо? Таблицю в базі, де є колонки id, name, email, is_active.
Все просто.
Приклад 2: Один-до-Багатьох (Реальний проєкт)
Тепер користувач хоче написати пост.
Питання: Як сказати базі, що цей пост належить саме цьому юзеру?
class Post(Model):
title = CharField(max_length=200)
content = TextField()
# МАГІЯ ТУТ 👇
author = ForeignKey(User, on_delete=CASCADE)
Розбір польотів:
1. ForeignKey — це "Зовнішній Ключ". Це стрілка, яка вказує на модель User.
2. on_delete=CASCADE — це дуже важливо! Це інструкція: "Якщо ми видалимо користувача, що робити з його постами?".
* CASCADE: Видалити і пости теж (щоб не було сміття).
* SET_NULL: Залишити пости, але в полі автора поставити "Анонім".
Приклад 3: Багато-до-Багатьох (Рівень PRO)
Теги! (Наприклад: #Technology, #Life, #Coding). Один пост може мати багато тегів. Один тег може бути на багатьох постах.
class Tag(Model):
name = CharField(max_length=50)
class Post(Model):
# ... попередні поля ...
tags = ManyToManyField(Tag)
Чому результат такий: Тут немає поля tags у таблиці постів. І немає поля posts у таблиці тегів. Система створила невидиму таблицю зв'язків. Це дозволяє нам додавати скільки завгодно тегів, не ламаючи структуру.
4. 🛠 Практична частина
Прийшов час забруднити руки кодом. Уявіть, що ви будуєте онлайн-магазин.
Завдання 1: Основа
Опишіть модель Product (Товар). Які поля їй потрібні?
(Підказка: назва, ціна, опис, чи є в наявності).
Завдання 2: Категоризація (One-to-Many)
Створіть модель Category (наприклад, "Електроніка", "Одяг"). Додайте зв'язок так, щоб один товар належав одній категорії, але в категорії було багато товарів.
Де буде прописаний ForeignKey — у Товарі чи в Категорії?
Завдання 3: Виправ помилку Студент написав такий код для системи курсів:
class Student(Model):
name = CharField()
courses_list = TextField() # Тут він пише: "Math, History, Physics"
Чому це погано? Як це переписати, використовуючи правильний тип зв'язку?
Завдання 4: Міні-кейс "Spotify"
У вас є Song (Пісня) і Playlist (Плейлист).
Який зв'язок між ними?
(Подумайте: чи може одна пісня бути в різних плейлистах?)
Завдання 5: А що, якщо...
Що станеться, якщо у завданні №2 ми видалимо категорію "Електроніка", а у нас є 1000 товарів у ній? Який параметр on_delete ви б обрали, щоб не втратити товари, а просто зробити їх "Без категорії"?
5. 💡 Мислення як у розробника
Як відрізнити новачка від профі, дивлячись на їхні моделі?
-
SSOT (Single Source of Truth): Новачок дублює дані ("збережу ім'я автора і в таблиці авторів, і в таблиці книг про всяк випадок"). Профі знає: дані мають зберігатися в одному місці. Якщо треба ім'я — ми "підтягнемо" його через зв'язок.
-
Типи даних мають значення: Новачок зберігає ціну як текст ("100$"). Профі зберігає як
Decimal, щоб потім можна було робити математику (знижки, податки) без болю. -
Неймінг: Погано:
class Table1, полеdata. Добре:class Order, полеcreated_at. Код читають люди, а не тільки машини. Називайте речі своїми іменами!
6. 🧩 Підсумок
Сьогодні ви зробили великий крок від простого зберігання даних до архітектури даних.
- Ми навчилися розбивати сутності на окремі таблиці (Моделі).
- Ми зрозуміли, як пов'язувати їх ниточками (Foreign Keys), щоб не дублювати інформацію.
- Ми дізналися, що база даних — це не просто склад, а розумний організм, який дбає про порядок.
Що далі? Тепер у нас є красива структура. Але як з неї дістати дані? Як запитати: "Дай мені всі товари з категорії 'Ноутбуки', дешевші за 1000 доларів, відсортовані за датою"?
На наступному уроці ми зануримось у ORM Queries (Запити) — мистецтво ставити правильні питання.
До зустрічі! 🚀