← Back to course

Типи Даних і Обмеження

Типи Даних і Обмеження

Вітаю знову.

У попередній лекції ти вивчив базові SQL-дії:

Ти навчився читати дані.

Додавати дані.

Змінювати дані.

Видаляти дані.

Дуже потужно.

І трохи небезпечно.

Сьогодні ми навчимося робити таблиці безпечнішими.

Бо база даних не повинна приймати все підряд.

Якщо колонка призначена для віку, вона не повинна приймати:

banana

Якщо email має бути унікальним, PostgreSQL повинен зупинити двох користувачів від використання одного й того самого email.

Якщо імʼя обовʼязкове, PostgreSQL не повинен дозволяти загадковим порожнім людям заходити в таблицю.

Саме тут допомагають типи даних і обмеження.

Типи даних визначають, який тип даних може зберігати колонка.

Обмеження визначають правила, яких дані мають дотримуватися.

Разом вони роблять базу даних сильнішою.

Як серйозний охоронець.

Але з крапками з комою.

Що Ти Вивчиш

У цій лекції ти вивчиш:

Наприкінці цієї лекції ти розумітимеш, як проєктувати таблиці, які не приймають дурниці.

Це важливо.

Бо погані дані — як блискітки.

Якщо вони один раз потрапили в систему, вони зʼявляються всюди.

Назавжди.

Що Таке Типи Даних?

Тип даних каже PostgreSQL, який тип значення може зберігати колонка.

Приклад:

CREATE TABLE students (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100),
  age INTEGER
);

Тут:

name VARCHAR(100)

означає, що колонка name зберігає текст.

А:

age INTEGER

означає, що колонка age зберігає цілі числа.

Отже PostgreSQL розуміє:

name = текст
age  = число

Це корисно, бо PostgreSQL може відхилити неправильні дані.

Якщо ти спробуєш вставити текст у колонку INTEGER, PostgreSQL буде протестувати.

І правильно.

Бази даних мають протестувати, коли приходять дурниці.

Тиша небезпечна.

Особливо в базах даних.

І на кухнях.

Чому Типи Даних Важливі

Уяви таку таблицю:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name TEXT,
  age TEXT
);

Технічно age тут є текстом.

Тому PostgreSQL може дозволити таке:

INSERT INTO users (name, age)
VALUES ('Anna', 'twenty two');

Або навіть таке:

INSERT INTO users (name, age)
VALUES ('Marco', 'banana');

Це погано.

Вік має бути числом.

Краще:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name TEXT,
  age INTEGER
);

Тепер PostgreSQL очікує число для age.

Це захищає твої дані.

Хороша структура блокує дурні дані ще до входу в таблицю.

PostgreSQL фактично каже:

Сьогодні без бананових віків.

Прекрасно.

Популярні Типи Даних у PostgreSQL

PostgreSQL має багато типів даних.

Сьогодні ми вивчимо найкорисніші для початківців:

Цього достатньо для багатьох beginner-проєктів.

Пізніше ти можеш дослідити більш advanced типи.

PostgreSQL має їх багато.

Бо PostgreSQL подивився на дані й сказав:

Так, я можу все це організувати.

Дуже амбітно.

Дуже корисно.

INTEGER

INTEGER зберігає цілі числа.

Приклад:

age INTEGER

Хороші значення:

18
25
100

Погані значення:

hello
25.5
banana

Приклад таблиці:

CREATE TABLE players (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100),
  score INTEGER
);

Встав дані:

INSERT INTO players (name, score)
VALUES ('Anna', 100);

Це працює.

Але це ні:

INSERT INTO players (name, score)
VALUES ('Marco', 'very good');

Бо score очікує число.

PostgreSQL відмовляє.

І правильно робить.

База даних без стандартів — це просто електронна таблиця з амбіціями.

VARCHAR

VARCHAR зберігає текст з максимальною довжиною.

Приклад:

name VARCHAR(100)

Це означає:

Імʼя може містити максимум 100 символів.

Приклад:

CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100),
  category VARCHAR(50)
);

Це добре для текстових полів, де потрібен розумний ліміт.

Наприклад:

Якщо ти спробуєш вставити текст довший за ліміт, PostgreSQL його відхилить.

Добре.

Іноді ліміти корисні.

Особливо для колонок бази даних.

І, можливо, для порцій піци.

TEXT

TEXT зберігає довгий текст.

Приклад:

description TEXT

Використовуй TEXT, коли тобі не потрібен суворий ліміт символів.

Добре підходить для:

Приклад:

CREATE TABLE articles (
  id SERIAL PRIMARY KEY,
  title VARCHAR(150),
  content TEXT
);

Тут:

title VARCHAR(150)

має ліміт.

А:

content TEXT

може бути довгим.

Це логічно.

Назва не повинна бути романом.

А поле content може ним бути.

PostgreSQL практичний.

Переважно.

BOOLEAN

BOOLEAN зберігає значення true або false.

Приклад:

available BOOLEAN

Хороші значення:

true
false

Приклад таблиці:

CREATE TABLE tasks (
  id SERIAL PRIMARY KEY,
  title VARCHAR(150),
  completed BOOLEAN
);

Встав дані:

INSERT INTO tasks (title, completed)
VALUES ('Learn PostgreSQL', false);

Пізніше можна оновити:

UPDATE tasks
SET completed = true
WHERE title = 'Learn PostgreSQL';

BOOLEAN ідеально підходить для значень так/ні:

Не зберігай це як текст:

yes
no
maybe
sort of

Там починається хаос.

Використовуй BOOLEAN.

Дозволь базі даних допомогти тобі.

DATE

DATE зберігає календарні дати.

Приклад:

birth_date DATE

Встав дату так:

'1992-10-23'

PostgreSQL любить формат:

YYYY-MM-DD

Приклад таблиці:

CREATE TABLE events (
  id SERIAL PRIMARY KEY,
  title VARCHAR(150),
  event_date DATE
);

Встав дані:

INSERT INTO events (title, event_date)
VALUES ('PostgreSQL Practice', '2026-05-03');

Дати мають бути датами.

Не текстом.

Не випадковими рядками.

Не “наступна пʼятниця, мабуть”.

PostgreSQL може нормально працювати з датами лише тоді, коли ти зберігаєш їх як дати.

Шок.

Але правда.

NUMERIC

NUMERIC зберігає точні десяткові числа.

Це корисно для грошей.

Приклад:

price NUMERIC(10, 2)

Це означає:

До 10 цифр загалом, з 2 цифрами після десяткової крапки.

Приклади значень:

49.99
100.00
1250.50

Приклад таблиці:

CREATE TABLE courses (
  id SERIAL PRIMARY KEY,
  title VARCHAR(150),
  price NUMERIC(10, 2)
);

Встав дані:

INSERT INTO courses (title, price)
VALUES ('PostgreSQL Basics', 49.99);

Для цін NUMERIC зазвичай краще, ніж INTEGER.

Хіба що ти зберігаєш центи як цілі числа.

Це теж нормальний підхід.

Але для початківців NUMERIC(10, 2) легко зрозуміти.

Гроші заслуговують точності.

Особливо коли вони виходять з твого рахунку.

SERIAL

SERIAL створює автоматично зростаюче ціле число.

Приклад:

id SERIAL PRIMARY KEY

Це означає, що PostgreSQL автоматично генерує ID.

Приклад:

CREATE TABLE students (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100)
);

Встав дані без id:

INSERT INTO students (name)
VALUES ('Anna');

PostgreSQL автоматично дасть Anna ID.

Потім наступний рядок отримає наступний ID.

І так далі.

Дуже корисно.

Не керуй ID вручну, якщо PostgreSQL може зробити це за тебе.

Життя й так складне.

Нехай база даних рахує.

Що Таке Обмеження?

Обмеження — це правила для даних у таблиці.

Вони кажуть PostgreSQL:

Це значення обовʼязкове.
Це значення має бути унікальним.
Це значення має відповідати умові.
Це значення має default.

Популярні обмеження:

Обмеження роблять таблиці безпечнішими.

Вони зупиняють погані дані до того, як ті потраплять у таблицю.

Думай про обмеження як про правила таблиці.

Наприклад:

Без порожніх імен.
Без дубльованих email.
Без негативних цін.
Без неможливого віку.

Дуже розумно.

PostgreSQL суворий.

Але тут суворість — це добре.

NOT NULL

NOT NULL означає, що колонка обовʼязкова.

Приклад:

name VARCHAR(100) NOT NULL

Це означає, що кожен рядок має мати імʼя.

Приклад таблиці:

CREATE TABLE customers (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(150)
);

Це працює:

INSERT INTO customers (name, email)
VALUES ('Anna', 'anna@example.com');

Це не працює:

INSERT INTO customers (email)
VALUES ('no-name@example.com');

Бо name обовʼязкове.

Добре.

Жодних загадкових customers без імен.

Це не база даних шпигунів.

Напевно.

UNIQUE

UNIQUE означає, що значення в колонці не можуть повторюватися.

Дуже корисно для email.

Приклад:

email VARCHAR(150) UNIQUE

Таблиця:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(150) UNIQUE
);

Встав першого користувача:

INSERT INTO users (name, email)
VALUES ('Anna', 'anna@example.com');

Це працює.

Спробуй вставити іншого користувача з тим самим email:

INSERT INTO users (name, email)
VALUES ('Another Anna', 'anna@example.com');

PostgreSQL це відхилить.

Бо email має бути унікальним.

Це захищає твої дані.

Без UNIQUE дублікати email можуть створити проблеми з login, account і головним болем.

Головний біль від бази даних не веселий.

Він носить важкі черевики.

DEFAULT

DEFAULT дає колонці значення, якщо ти нічого не передав.

Приклад:

active BOOLEAN DEFAULT true

Таблиця:

CREATE TABLE subscribers (
  id SERIAL PRIMARY KEY,
  email VARCHAR(150) UNIQUE NOT NULL,
  active BOOLEAN DEFAULT true
);

Встав без active:

INSERT INTO subscribers (email)
VALUES ('reader@example.com');

Тепер перевір:

SELECT * FROM subscribers;

Колонка active має бути true.

PostgreSQL використав значення за замовчуванням.

Default-и корисні, коли більшість рядків має починатися з одного й того самого значення.

Наприклад:

Хороші default-и зменшують повторення коду.

А повторення коду — це місце, де маленькі bugs будують гнізда.

CHECK

CHECK створює правило, якому значення мають відповідати.

Приклад:

price NUMERIC(10, 2) CHECK (price >= 0)

Це означає, що ціна не може бути негативною.

Таблиця:

CREATE TABLE store_products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  price NUMERIC(10, 2) CHECK (price >= 0)
);

Це працює:

INSERT INTO store_products (name, price)
VALUES ('Mouse', 25.00);

Це не працює:

INSERT INTO store_products (name, price)
VALUES ('Magic Refund Product', -10.00);

PostgreSQL це відхилить.

Добре.

Негативні ціни можуть існувати в бухгалтерії.

Але не в цій таблиці.

База даних захищає правило.

Дуже серйозно.

Дуже корисно.

CHECK з Віком

Інший приклад:

age INTEGER CHECK (age >= 0)

Це означає, що вік не може бути негативним.

Таблиця:

CREATE TABLE people (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  age INTEGER CHECK (age >= 0)
);

Це працює:

INSERT INTO people (name, age)
VALUES ('Anna', 22);

Це не працює:

INSERT INTO people (name, age)
VALUES ('Time Traveler', -5);

PostgreSQL відмовляє.

Добре.

Якщо тобі потрібні мандрівники в часі, створи окрему таблицю.

Можливо.

Поєднання Обмежень

Можна поєднувати кілька обмежень в одній таблиці.

Приклад:

CREATE TABLE app_users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(150) UNIQUE NOT NULL,
  active BOOLEAN DEFAULT true,
  age INTEGER CHECK (age >= 0)
);

Ця таблиця має багато правил:

Це набагато безпечніше, ніж таблиця без правил.

Таблиця без обмежень приймає забагато.

Вона занадто ввічлива.

Бази даних не мають бути занадто ввічливими.

Вони мають захищати дані.

Як серйозний фейс-контроль у клубі інформації.

Створи Безпечнішу Таблицю Products

Створімо кращу таблицю products.

Спочатку видали стару, якщо потрібно:

DROP TABLE IF EXISTS safe_products;

Тепер створи:

CREATE TABLE safe_products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  category VARCHAR(100) DEFAULT 'General',
  price NUMERIC(10, 2) CHECK (price >= 0),
  available BOOLEAN DEFAULT true
);

Ця таблиця має кращі правила:

Встав дані:

INSERT INTO safe_products (name, price)
VALUES ('Laptop', 900.00);

Перевір:

SELECT * FROM safe_products;

Ти маєш побачити:

category = General
available = true

PostgreSQL заповнив default-и.

Приємно.

База даних допомагає.

Нарешті.

Протестуй Правила

Спробуй вставити товар без назви:

INSERT INTO safe_products (price)
VALUES (10.00);

PostgreSQL має відхилити це, бо name є NOT NULL.

Спробуй вставити негативну ціну:

INSERT INTO safe_products (name, price)
VALUES ('Broken Product', -5.00);

PostgreSQL має відхилити це через CHECK.

Це добре.

Таблиця захищається сама.

Таблиця, яка захищається сама, набагато безпечніша за таблицю, яка приймає все.

Як двері із замком.

Не ідеально.

Але краще, ніж штора.

Перевір Таблицю

Виконай:

\d safe_products

Ти маєш побачити колонки, типи, default-и й constraints.

Це корисна команда.

Використовуй її часто.

Коли забудеш, як виглядає таблиця, запитай PostgreSQL.

Він памʼятає.

Він завжди памʼятає.

Дуже базоданно.

Трохи страшно.

Типові Помилки

Використовувати TEXT для Всього

Погано:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name TEXT,
  age TEXT,
  active TEXT
);

Краще:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100),
  age INTEGER,
  active BOOLEAN
);

Використовуй правильний тип.

Text — це не універсальне рішення.

Це корисний інструмент.

Не сміттєвий пакет для storage.

Забути NOT NULL

Погано:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(150)
);

Це дозволяє створювати користувачів без імен або email.

Можливо, це не те, що ти хочеш.

Краще:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL
);

Якщо значення обовʼязкове, скажи це.

PostgreSQL буде це контролювати.

Забути UNIQUE для Email

Погано:

email VARCHAR(150)

Краще:

email VARCHAR(150) UNIQUE

Якщо email ідентифікує користувачів, зазвичай він має бути унікальним.

Дублікати email — це як дві людини з одним паспортом.

Можливо в поганій системі.

Жахлива ідея.

Дозволяти Негативні Ціни

Погано:

price NUMERIC(10, 2)

Краще:

price NUMERIC(10, 2) CHECK (price >= 0)

Якщо негативні ціни не мають сенсу, заблокуй їх.

Не довіряй майбутньому коду, що він завжди буде чемним.

Майбутній код пишуть майбутні люди.

Небезпечно.

Практика

Створи таблицю з назвою employees.

Вона має мати:

Використай ці правила:

Приклад:

CREATE TABLE employees (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(150) UNIQUE NOT NULL,
  salary NUMERIC(10, 2) CHECK (salary >= 0),
  active BOOLEAN DEFAULT true,
  hired_at DATE
);

Встав employees:

INSERT INTO employees (name, email, salary, hired_at)
VALUES ('Anna', 'anna@example.com', 2500.00, '2026-05-03');
INSERT INTO employees (name, email, salary, active, hired_at)
VALUES ('Marco', 'marco@example.com', 3000.00, false, '2026-05-04');

Прочитай дані:

SELECT * FROM employees;

Потім протестуй constraints.

Спробуй дубльований email.

Спробуй негативну salary.

Спробуй відсутнє name.

Дозволь PostgreSQL тебе зупинити.

У цьому й сенс.

Мінічелендж

Створи таблицю з назвою courses.

Вона має мати:

Правила:

Підказка:

created_at DATE DEFAULT CURRENT_DATE

Встав щонайменше три курси.

Потім виконай:

SELECT * FROM courses;

Спробуй вставити курс без title.

Спробуй вставити курс з негативною price.

PostgreSQL має відхилити погані дані.

Це не PostgreSQL дратує тебе.

Це PostgreSQL корисний.

Є різниця.

Іноді.

Підсумок

Сьогодні ти вивчив:

Це великий крок.

Ти вже не просто створюєш таблиці.

Ти створюєш безпечніші таблиці.

База даних не повинна приймати дурниці.

Вона має захищати структуру.

Вона має відхиляти погані дані.

Вона має зупиняти бананові віки, дубльовані email, негативні ціни й загадкових порожніх користувачів.

PostgreSQL може це робити.

Якщо ти даси йому правила.

Наступна Лекція

У наступній лекції ми навчимося фільтрувати й сортувати дані.

Ми глибше розберемо:

Бо коли в тебе є дані, потрібно знайти правильні дані.

Не всі дані.

Правильні дані.

Саме тут запити стають цікавими.

І трохи небезпечними.