Ось урок, створений спеціально для вас у стилі CS50: енергійний, зрозумілий та практичний.
🎓 CS50 Style: PostgreSQL Data Types
Або: Чому не можна зберігати суп у картонній коробці?
Привіт усім! 👋
Уявіть, що ви переїжджаєте в нову квартиру. У вас є купа речей: книги, одяг, посуд і... ну, скажімо, акваріум з рибками. Ви ж не будете складати акваріум у картонну коробку для книг? Чому? Тому що коробка розмокне, рибки (на жаль) постраждають, а ви отримаєте безлад.
База даних — це ваша вантажівка для переїзду. А типи даних — це спеціалізовані контейнери.
1. 🔥 Вступ: Проблема та мотивація
Давайте почнемо з реального життя. Уявіть, що ви будуєте банківський додаток. Ви створили таблицю і для балансу рахунку вибрали... ну, просто "текст".
Ви пишете: Баланс: "100.50".
Потім клієнт додає ще 50.
База даних каже: "Окей, я додам текст до тексту".
Результат: "100.5050".
Чекайте, що?! 😱 Замість 150.50 ми отримали нісенітницю.
Або ще гірше: ви зберігаєте дати як текст "01-02-2024". Як відсортувати їх? Комп'ютер почне сортувати за алфавітом, і "10-01-2023" раптом стане "більшим" за "02-01-2024".
Питання до вас: Чи хотіли б ви, щоб ваша зарплата розраховувалася з такою "текстовою" логікою? Впевнений, що ні.
Навіщо нам типи даних?
1. Цілісність (Integrity): Щоб у поле "Вік" ніхто випадково не записав слово "привіт".
2. Ефективність: Числу 42 потрібно всього 4 байти пам'яті. Тексту "сорок два" — значно більше. На мільярдах записів це гігабайти різниці.
3. Магія операцій: Якщо база знає, що це дата, вона дозволяє робити круті штуки, наприклад: дата + 7 днів.
2. 🧠 Теоретична база (Але без нудних лекцій)
PostgreSQL — це "Typed" (типізована) система. Це означає, що вона дуже сувора. Вона як педантичний бібліотекар: якщо книга стоїть не на тій полиці, вона не дозволить вам її туди поставити.
Давайте розглянемо "Велику Четвірку" типів, які покривають 90% ваших потреб.
А. Числа (Numbers)
Тут є пастка! ⚠️ * INTEGER (INT): Цілі числа (1, 50, -100). Використовуємо для кількості, ID, віку. * NUMERIC / DECIMAL: Числа з комою, де точність критична. Це для грошей! 💸 PostgreSQL зберігає їх точно, до копійки. * REAL / DOUBLE PRECISION: Числа з "плаваючою комою". Вони швидкі, але... трохи неточні. * Інтуїція: Це як відміряти борошно склянкою. Швидко, але не ідеально точно. Для наукових розрахунків — ок. Для грошей — НІКОЛИ.
Б. Текст (Text)
У старих базах даних (як старий MySQL) були дивні обмеження. У Postgres все простіше:
* TEXT: Універсальний солдат. Може зберігати будь-яку довжину. Postgres оптимізує його "під капотом" ідеально.
* VARCHAR(n): Текст з обмеженням до n символів. Використовуйте тільки якщо бізнес-логіка вимагає обмеження (наприклад, код країни з 2 літер).
В. Логіка (Boolean)
- BOOLEAN: Тільки
TRUE(так),FALSE(ні) абоNULL(невідомо).- Приклад:
is_active,has_paid. Це маленький перемикач світла. 💡
- Приклад:
Г. Час (Date/Time)
- DATE: Просто дата (2024-01-27). Календар на стіні.
- TIMESTAMP: Дата + Час.
- TIMESTAMPTZ (З запам'ятовуванням часового поясу): 🔥 Золотий стандарт.
- Чому це важливо: Якщо ваш сервер у Києві, а клієнт у Нью-Йорку,
TIMESTAMPTZзбереже момент часу в UTC, і кожен побачить свій правильний час. Без цього ви будете жити в пеклі часових поясів.
- Чому це важливо: Якщо ваш сервер у Києві, а клієнт у Нью-Йорку,
3. 🧪 Приклади (Coding Time!)
Давайте відкриємо термінал. Уявімо, ми робимо магазин кросівок.
Крок 1: Створюємо таблицю (Креслення)
CREATE TABLE sneakers (
id SERIAL PRIMARY KEY, -- SERIAL: авто-лічильник (1, 2, 3...)
model_name TEXT NOT NULL, -- Назва: текст будь-якої довжини
size INT CHECK (size > 0), -- Розмір: ціле число (і ми додали перевірку!)
price NUMERIC(10, 2), -- Ціна: 10 цифр всього, 2 після коми. Точність!
is_in_stock BOOLEAN DEFAULT true,-- Чи є в наявності? За замовчуванням - так.
created_at TIMESTAMPTZ DEFAULT NOW() -- Коли додали? Автоматично ставимо "зараз".
);
Що ви очікуєте, якщо ми виконаємо цей код?
Postgres скаже CREATE TABLE. Він створив порожню "шафу" з підписаними полицями.
Крок 2: Додаємо дані (Happy Path)
INSERT INTO sneakers (model_name, size, price)
VALUES ('Air Jordan 1', 42, 199.99);
Все чудово. Postgres сам додав id (1), is_in_stock (true) і час створення.
Крок 3: Спроба зламати систему (Fail Path)
А тепер спробуємо запхати "суп у картонну коробку":
INSERT INTO sneakers (model_name, size, price)
VALUES ('Bad Data Shoes', 'forty-two', 'expensive');
Результат:
ERROR: invalid input syntax for type integer: "forty-two"
💥 Бум! Postgres захистив нас від дурниць. Він не дозволив записати сміття в базу. Ось чому типи даних — це ваші охоронці.
4. 🛠 Практична частина
Тепер ваша черга! Відкрийте свій SQL-редактор (або уявіть його).
Завдання 1: "Мрійник"
Створіть таблицю goals (цілі). Вона повинна мати:
* Текст цілі.
* Дату, до якої треба виконати (deadline).
* Чи виконана вона (is_done).
* Складність від 1 до 10 (використайте INTEGER).
Завдання 2: "Гроші на вітер"
Спробуйте створити таблицю з полем wallet_balance типу REAL (плаваюча кома). Вставте туди 100.1 і 200.2. Зробіть SELECT, де ви додаєте ці числа.
Спойлер: ви можете отримати щось типу 300.2999999999999. Поясніть собі, чому це погано для банку.
Завдання 3: "Виправ помилку"
У вас є запит:
INSERT INTO goals (deadline) VALUES ('tomorrow');
Це не спрацює. Чому? Як правильно записати завтрашню дату у форматі SQL (ISO 8601)?
Завдання 4: Міні-кейс
Вам треба зберігати налаштування користувача (тема: темна/світла, сповіщення: вкл/викл, мова: ua).
Створювати окрему колонку для кожного налаштування — це довго і нудно, бо налаштування часто змінюються.
Підказка: Погугліть тип даних JSONB у PostgreSQL. Це суперсила Postgres. Спробуйте створити таблицю з полем settings JSONB.
5. 💡 Мислення як у розробника
Як думає Senior-розробник, коли проектує базу?
-
"Який найгірший сценарій?"
- Новачок думає: "Ціна — це просто число".
- Профі думає: "Числа бувають неточні. Я візьму
NUMERIC, щоб бухгалтер мене не вбив".
-
"Чи буду я за цим шукати?"
- Якщо ви зберігаєте дату як текст
"2024/01", ви не зможете ефективно шукати "всі записи за січень". Використовуйте нативні типи (DATE,TIMESTAMP), бо вони індексуються і працюють блискавично.
- Якщо ви зберігаєте дату як текст
-
Порада на мільйон: Не бійтеся типу
TEXTу Postgres. В інших базах кажуть "використовуйVARCHAR(255), щоб економити місце". У PostgresTEXTіVARCHARпрацюють майже однаково швидко. Якщо не треба жорсткого ліміту — берітьTEXTі живіть спокійно. -
Час — це біль. Завжди, чуєте, ЗАВЖДИ використовуйте
TIMESTAMPTZ(timestamp with time zone). Навіть якщо ваш проект лише для одного міста. Бізнес росте, сервери переїжджають.TIMESTAMPTZ— це ваша страховка.
6. 🧩 Підсумок
Отже, що ми маємо сьогодні?
- База даних — це не смітник, це аптека. Все має бути на своїх місцях і підписане.
- Типи даних визначають, що можна робити з інформацією (додавати, сортувати, обрізати).
- Ви навчилися відрізняти
INTвідNUMERICі знаєте, чомуTIMESTAMPTZ— ваш найкращий друг. - Ви тепер вмієте створювати "креслення" для надійних таблиць.
Тепер ви вмієте: Проектувати надійний фундамент для даних, який не розвалиться під навантаженням.
🚀 Тизер:
Але стривайте! Ми навчилися зберігати дані. А що, якщо у нас мільйон кросівок, і нам треба знайти всі червоні 42-го розміру за 0.01 секунди? Простого SELECT буде замало...
На наступному уроці ми поговоримо про Індекси (Indexes) — як перетворити вашу базу даних з повільної черепахи на ракету.
Це був CS50. (Тобто, наш урок). Побачимось! 🎬