Вибір типу даних — це як вибір інструменту для роботи. Ти ж не будеш використовувати викрутку, щоб забити цвях (сподіваюсь). Так само і в базі даних: правильний тип даних суттєво впливає на продуктивність, економію пам’яті та зручність керування даними. Наприклад, якщо ми зберігаємо гроші у форматі REAL, то можемо отримати проблеми з точністю, а використання TEXT замість VARCHAR для коротких рядків збільшує обсяг пам’яті, яку займає база.
При виборі типу даних враховуй кілька факторів:
Характер даних
Визнач, до якої категорії належать дані: числа, рядки, логічні значення, дати чи щось складніше, наприклад, JSON-структури.
Обсяг даних
Скільки даних ти плануєш зберігати? Наприклад, для текстів до 50 символів краще обрати VARCHAR(50) замість TEXT.
Точність і діапазон
Чи потрібно підтримувати високу точність (наприклад, для фінансових розрахунків)? Хочеш обмежити діапазон значень?
Частота і характер запитів
Як часто ти будеш звертатись до даних? Враховуй, що складні типи, такі як JSONB, потребують більше ресурсів на обробку.
Приклади вибору типів даних
Різні дані — різні задачі. Десь важлива точність до копійки, а десь — просто щоб усе влізло. Нижче приклади, як підібрати підходящий тип даних під конкретну ситуацію.
Фінансові дані
Коли справа доходить до зберігання грошей, як і в бухгалтерії, помилки неприпустимі. Тому найкращим вибором буде тип NUMERIC, який забезпечує високу точність. Наприклад, ми хочемо таблицю з такими колонками:
| Ім’я колонки | Тип даних | Коментар |
|---|---|---|
| id | SERIAL | Первинний ключ |
| amount | NUMERIC(10, 2) | Десять цифр, з яких дві — після коми |
| currency_code | CHAR(3) | ISO-код валюти, наприклад "USD", "EUR" |
| transaction_date | TIMESTAMP | Час транзакції, за замовчуванням — поточний час |
Чому не REAL? Справа в тому, що числа з плаваючою комою можуть втрачати точність, а це критично для фінансів.
Текстові дані
Якщо ти збираєшся зберігати імена користувачів, адреси чи будь-які інші рядки, завжди задавай максимальну довжину, коли це можливо. Наприклад, VARCHAR(50) замість TEXT. Це допомагає уникнути можливих помилок і оптимізує пам’ять.
| Ім’я колонки | Тип даних | Коментар |
|---|---|---|
| id | SERIAL | Первинний ключ |
| username | VARCHAR(50) | Логін користувача, унікальний і обов’язковий |
| VARCHAR(255) | Електронна пошта | |
| bio | TEXT | Біографія, наприклад, текст великої довжини |
Якщо довжина рядка строго фіксована (наприклад, двозначні коди країни), використовуй CHAR:
| Ім’я колонки | Тип даних | Коментар |
|---|---|---|
| code | CHAR(2) | ISO код країни (наприклад, "US"), первинний ключ |
| name | VARCHAR(100) | Назва країни, обов’язково для заповнення |
Дані для часових міток
Для зберігання часу подій або розкладів найчастіше підійде TIMESTAMP, бо він одночасно містить дату і час.
| Ім’я колонки | Тип даних | Коментар |
|---|---|---|
| id | SERIAL | Первинний ключ |
| event_name | VARCHAR(100) | Назва події |
| start_time | TIMESTAMP | Час початку події, обов’язково |
| end_time | TIMESTAMP | Час закінчення події, обов’язково |
Якщо потрібно лише час без дати, використовуй TIME, а якщо лише дату без часу — DATE.
Унікальні ідентифікатори
Коли треба створювати ідентифікатори, які будуть унікальні на глобальному рівні, використовуй UUID. Наприклад, для генерації унікального ідентифікатора транзакції:
| Ім’я колонки | Тип даних | Коментар |
|---|---|---|
| request_id | UUID | Унікальний ідентифікатор запиту, генерується за замовчуванням через gen_random_uuid() |
| endpoint | VARCHAR(255) | Адреса викликаного API-ендпоінта |
| timestamp | TIMESTAMP | Час запиту, за замовчуванням — поточний час |
JSONB: складні структури
Коли треба зберігати дані, структура яких може змінюватись або бути складною, наприклад, користувацькі налаштування чи метадані, використовуй JSONB.
| Ім’я колонки | Тип даних | Коментар |
|---|---|---|
| user_id | SERIAL | Первинний ключ (ID користувача) |
| preferences | JSONB | Налаштування користувача у форматі JSON |
З JSONB зручно працювати, але варто враховувати, що це може знижувати продуктивність при великій кількості вставок/оновлень.
Масиви
Масиви підходять, якщо треба зберігати списки однорідних даних. Наприклад, список тегів:
| Ім’я колонки | Тип даних | Коментар |
|---|---|---|
| id | SERIAL | Первинний ключ |
| title | VARCHAR(255) | Заголовок статті |
| tags | TEXT[] | Масив тегів |
Огляд типів даних за задачами
| Тип задачі | Рекомендований тип даних | Приклад |
|---|---|---|
| Ідентифікатор запису | SERIAL, BIGSERIAL, UUID |
id SERIAL PRIMARY KEY |
| Кількість, цілі числа | INTEGER, BIGINT |
quantity INTEGER |
| Фінансові розрахунки | NUMERIC |
price NUMERIC(10, 2) |
| Зберігання рядків | VARCHAR(n), TEXT |
username VARCHAR(50) |
| Короткі фіксовані рядки | CHAR(n) |
status CHAR(1) |
| Дати і час | DATE, TIME, TIMESTAMP |
created_at TIMESTAMP DEFAULT NOW() |
| Унікальні ідентифікатори | UUID |
id UUID PRIMARY KEY DEFAULT gen_random_uuid() |
| Складні структури (JSON) | JSONB |
metadata JSONB |
| Списки значень | ARRAY |
tags TEXT[] |
| Логічне значення | BOOLEAN |
is_active BOOLEAN |
Ти, мабуть, вже знайомий з усіма типами, окрім SERIAL. Вся справа в тому, що SERIAL — це фактично той самий INTEGER, який використовується як ідентифікатор рядків у таблицях.
Він автоматично збільшується на 1 при додаванні нового рядка в таблицю. Тобто, якщо додати в таблицю 10 рядків, то у першого рядка id буде 1, у другого — 2 і т.д. Детальніше про це все ти дізнаєшся в наступній лекції :)
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ