Модуль 8

Типи полів та обмеження

Ось готовий урок, створений у стилі CS50 спеціально для тебе.


🎓 Урок CS50: Типи полів та Обмеження (Data Types & Constraints)

Привіт, друзі! Це CS50.

Сьогодні ми поговоримо про одну з фундаментальних речей у світі даних. Це тема, яка відрізняє професійний застосунок від хаосу, записаного на серветці. Ми поговоримо про Типи полів та Обмеження (Constraints) у базах даних.


1. 🔥 Вступ: проблема та мотивація

Уявіть, що ви організовуєте величезну вечірку. Ви даєте гостям чистий аркуш паперу і просите написати їхній вік.

  • Один гість пише: 25.
  • Інший пише: Двадцять п'ять.
  • Третій пише: Майже 30.
  • Четвертий взагалі малює смайлик 🙂.

А тепер уявіть, що вам потрібно, щоб комп’ютер автоматично порахував середній вік гостей. Що станеться? Комп’ютер "вибухне". Він не знає, як додати число 25 до слова "Майже".

Або ще гірше: уявіть банківський додаток. Ви хочете переказати 100 гривень, але через помилку в системі на вашому рахунку з'являється -500 гривень, або в полі "Валюта" хтось випадково записав Banana.

Чому без цього не обійтись? База даних — це не просто смітник для інформації. Це структура. Якщо ми не встановимо жорсткі правила на вході, ми отримаємо сміття на виході. У програмуванні є навіть такий термін: GIGO (Garbage In, Garbage Out).

Сьогодні ми навчимося будувати "фейс-контроль" для наших даних.


2. 🧠 Теоретична база (Що "під капотом"?)

Коли ви створюєте таблицю в базі даних (наприклад, SQL), ви маєте відповісти на два питання для кожного стовпчика: 1. Який це тип даних? (Число? Текст? Дата?) 2. Які є обмеження? (Чи може бути пустим? Чи має бути унікальним?)

🔹 Типи даних (Data Types)

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

  • INT (Integer): Цілі числа (1, 50, -100). Використовуємо для кількості, віку, ID.
    • Чому це важливо: Арифметика з числами працює швидко.
  • VARCHAR(n): Текст змінної довжини (ім'я, email). n — це максимальна кількість символів.
    • Аналогія: Коробка, яка розтягується під розмір вмісту, але має ліміт.
  • BOOLEAN: Так або Ні (True/False).
    • Приклад: Чи активний користувач? Чи оплачено замовлення?
  • DECIMAL / FLOAT: Дробові числа.
    • Увага: Для грошей завжди використовуємо DECIMAL (точність), а не FLOAT (приблизність). Про це згодом.

🔹 Обмеження (Constraints)

Це ваші охоронці. Вони стоять на вході в таблицю і кажуть: "Ти не пройдеш!".

  1. NOT NULL: Поле не може бути порожнім. (Уявіть паспорт без прізвища — неможливо).
  2. UNIQUE: Значення не може повторюватися. (Два користувачі не можуть мати однаковий email).
  3. CHECK: Перевірка умови. (Ціна не може бути меншою за 0).
  4. PRIMARY KEY: Головний ідентифікатор. Це комбінація NOT NULL + UNIQUE. Це як ваш ідентифікаційний код.

Інтуїтивно: Тип даних каже "Якою мовою ми говоримо", а Обмеження кажуть "Що саме дозволено говорити".


3. 🧪 Приклади (від простого до реального)

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

Спроба №1: Хаос (Без типів і обмежень)

(Умовно, якби SQL дозволяв таке неподобство)

Table: Products
Name        Price       InStock
"iPhone"    1000        Yes
"Samsung"   "Cheap"     5
NULL        -50         Unknown

Питання до вас: Як нам знайти найдорожчий товар? Ніяк. "Cheap" не порівняти з 1000. Це провал.

Спроба №2: Додаємо типи (SQL)

CREATE TABLE Products (
    id INT,
    name VARCHAR(50),
    price DECIMAL(10, 2), -- 10 цифр всього, 2 після коми
    is_active BOOLEAN
);

Що ми отримали: Тепер ми не можемо записати слово "Cheap" у поле price. База даних видасть помилку. Але є проблема: Ми все ще можемо створити товар без назви (NULL) або два товари з однаковим ID.

Спроба №3: Реальний "Production" рівень 🚀

CREATE TABLE Products (
    id INT PRIMARY KEY,           -- Унікальний ID, обов'язковий
    name VARCHAR(50) NOT NULL,    -- Товар мусить мати назву
    price DECIMAL(10, 2) CHECK (price >= 0), -- Ціна не може бути від'ємною!
    sku VARCHAR(20) UNIQUE,       -- Артикул має бути унікальним
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Автоматичний час створення
);

Чому це круто? 1. Спробуйте додати товар з ціною -100. База скаже: Error: CHECK constraint failed. 2. Спробуйте додати два товари з однаковим артикулом (sku). База скаже: Error: UNIQUE constraint failed. 3. Забули вказати дату? База сама поставить поточний час.

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


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

Час забруднити руки кодом (або логікою). Ось ваші завдання:

  1. 🔹 Повторити: Напишіть SQL-запит для створення таблиці Users з полями:

    • id (ціле число, головний ключ)
    • username (текст до 30 символів)
    • age (ціле число)
  2. 🔹 Виправити помилку: У вас є поле email. Які два обмеження (constraints) ви обов'язково маєте додати до нього, щоб система реєстрації працювала коректно?

  3. 🔹 А що, якщо: Ви створюєте таблицю для бібліотеки. Поле date_returned (дата повернення книги).

    • Який тип даних обрати?
    • Чи може це поле бути NULL? (Підказка: книга ще може бути у читача).
  4. 🔹 Міні-кейс: Спроєктуйте таблицю Orders (Замовлення). Вам потрібно зберігати:

    • Номер замовлення.
    • Адресу доставки (обов'язково).
    • Суму замовлення (не може бути 0 або менше).
    • Статус (наприклад: "new", "shipped"). Бонус: як обмежити статус лише цими варіантами?
  5. 🔹 Логічна пастка: Чому для збереження телефонного номера (наприклад, +380501234567) поганою ідеєю є використання типу INT (число)?


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

Як думає досвідчений інженер, коли проєктує базу?

  1. "База даних — це остання лінія оборони". Ви можете перевіряти дані на сайті (JavaScript), ви можете перевіряти їх на сервері (Python/Java). Але завжди додавайте обмеження в базу. Чому? Бо колись інший розробник (або ви самі через рік) підключиться до бази напряму і випадково зіпсує дані. Constraints не дадуть цього зробити.

  2. Пастка з грошима. Новачки часто використовують тип FLOAT або DOUBLE для грошей.

    • Проблема: Комп’ютери неточно зберігають дробові числа. 0.1 + 0.2 в комп'ютері часто дорівнює 0.30000000000000004.
    • Рішення: Для фінансів завжди використовуйте DECIMAL (фіксована точність) або зберігайте все в копійках як INT.
  3. Економія простору. Якщо ви знаєте, що код країни завжди має 2 літери (UA, US, DE), використовуйте CHAR(2), а не VARCHAR(100). Це показує, що ви розумієте природу своїх даних.


6. 🧩 Підсумок

Отже, що ми сьогодні зрозуміли?

  1. Типи даних визначають, що ми зберігаємо (числа, текст, дати).
  2. Обмеження (Constraints) визначають правила гри (не пусте, унікальне, більше нуля).
  3. Добре спроєктована таблиця сама захищає себе від помилок.

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

Тизер: Але стривайте! У нас є таблиця Users і таблиця Orders. Як нам сказати базі даних, що "Ось це замовлення належить ось цьому користувачу"? На наступному уроці ми поговоримо про "магічний клей" баз даних — Зв'язки (Relations) та Зовнішні ключі (Foreign Keys).

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