Typy Danych i Ograniczenia

Witaj z powrotem.
W poprzedniej lekcji nauczyłeś się podstawowych akcji SQL:
SELECT;INSERT;UPDATE;DELETE.
Nauczyłeś się czytać dane.
Dodawać dane.
Zmieniać dane.
Usuwać dane.
Bardzo potężne.
I trochę niebezpieczne.
Dzisiaj nauczymy się, jak robić bezpieczniejsze tabele.
Bo baza danych nie powinna akceptować wszystkiego.
Jeśli kolumna jest dla wieku, nie powinna przyjmować:
banana
Jeśli email musi być unikalny, PostgreSQL powinien zatrzymać dwóch użytkowników przed użyciem tego samego emaila.
Jeśli imię jest wymagane, PostgreSQL nie powinien pozwalać tajemniczym pustym ludziom wejść do tabeli.
Tutaj pomagają typy danych i ograniczenia.
Typy danych określają, jaki rodzaj danych może przechowywać kolumna.
Ograniczenia określają reguły, których dane muszą przestrzegać.
Razem robią bazę danych silniejszą.
Jak poważny ochroniarz.
Ale ze średnikami.
Czego Się Nauczysz
W tej lekcji nauczysz się:
- czym są typy danych;
- dlaczego typy danych mają znaczenie;
- jak używać
INTEGER; - jak używać
VARCHAR; - jak używać
TEXT; - jak używać
BOOLEAN; - jak używać
DATE; - jak używać
NUMERIC; - czym są ograniczenia;
- jak używać
NOT NULL; - jak używać
UNIQUE; - jak używać
DEFAULT; - jak używać
CHECK; - jak tworzyć bezpieczniejsze tabele;
- jak PostgreSQL chroni twoje dane przed chaosem.
Na końcu tej lekcji będziesz rozumieć, jak projektować tabele, które nie przyjmują bzdur.
To ważne.
Bo złe dane są jak brokat.
Kiedy raz wejdą do systemu, pojawiają się wszędzie.
Na zawsze.
Czym Są Typy Danych?
Typ danych mówi PostgreSQL, jaki typ wartości może przechowywać kolumna.
Przykład:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age INTEGER
);
Tutaj:
name VARCHAR(100)
oznacza, że kolumna name przechowuje tekst.
A:
age INTEGER
oznacza, że kolumna age przechowuje liczby całkowite.
Więc PostgreSQL rozumie:
name = tekst
age = liczba
To jest przydatne, bo PostgreSQL może odrzucić złe dane.
Jeśli spróbujesz włożyć tekst do kolumny INTEGER, PostgreSQL będzie protestował.
Dobrze.
Bazy danych powinny protestować, kiedy przychodzą bzdury.
Cisza jest niebezpieczna.
Szczególnie w bazach danych.
I w kuchniach.
Dlaczego Typy Danych Mają Znaczenie
Wyobraź sobie taką tabelę:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT,
age TEXT
);
Technicznie age jest tutaj tekstem.
Więc PostgreSQL może pozwolić na coś takiego:
INSERT INTO users (name, age)
VALUES ('Anna', 'twenty two');
Albo nawet:
INSERT INTO users (name, age)
VALUES ('Marco', 'banana');
To jest złe.
Wiek powinien być liczbą.
Lepiej:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT,
age INTEGER
);
Teraz PostgreSQL oczekuje liczby dla age.
To chroni twoje dane.
Dobra struktura blokuje głupie dane przed wejściem do tabeli.
PostgreSQL w praktyce mówi:
Dzisiaj bez bananowych wieków.
Świetnie.
Popularne Typy Danych w PostgreSQL
PostgreSQL ma wiele typów danych.
Dzisiaj nauczymy się najważniejszych dla początkujących:
INTEGER;VARCHAR;TEXT;BOOLEAN;DATE;NUMERIC;SERIAL.
To wystarczy dla wielu początkujących projektów.
Później możesz poznać bardziej zaawansowane typy.
PostgreSQL ma ich dużo.
Bo PostgreSQL spojrzał na dane i powiedział:
Tak, mogę to wszystko uporządkować.
Bardzo ambitnie.
Bardzo użytecznie.
INTEGER
INTEGER przechowuje liczby całkowite.
Przykład:
age INTEGER
Dobre wartości:
18
25
100
Złe wartości:
hello
25.5
banana
Przykładowa tabela:
CREATE TABLE players (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
score INTEGER
);
Wstaw dane:
INSERT INTO players (name, score)
VALUES ('Anna', 100);
To działa.
Ale to nie:
INSERT INTO players (name, score)
VALUES ('Marco', 'very good');
Bo score oczekuje liczby.
PostgreSQL odmawia.
I bardzo dobrze.
Baza danych bez standardów to tylko arkusz kalkulacyjny z ambicjami.
VARCHAR
VARCHAR przechowuje tekst z maksymalną długością.
Przykład:
name VARCHAR(100)
To oznacza:
Imię może mieć maksymalnie 100 znaków.
Przykład:
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
category VARCHAR(50)
);
To dobre dla pól tekstowych, gdzie chcesz rozsądny limit.
Na przykład:
- imiona;
- tytuły;
- emaile;
- kategorie;
- krótkie etykiety.
Jeśli spróbujesz wstawić tekst dłuższy niż limit, PostgreSQL go odrzuci.
Dobrze.
Czasami limity są zdrowe.
Szczególnie dla kolumn w bazie danych.
I może dla porcji pizzy.
TEXT
TEXT przechowuje długi tekst.
Przykład:
description TEXT
Używaj TEXT, kiedy nie potrzebujesz sztywnego limitu znaków.
Dobre dla:
- opisów;
- treści artykułów;
- komentarzy;
- notatek;
- długich wiadomości.
Przykład:
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title VARCHAR(150),
content TEXT
);
Tutaj:
title VARCHAR(150)
jest ograniczony.
Ale:
content TEXT
może być długi.
To ma sens.
Tytuł nie powinien być powieścią.
Pole content może nią być.
PostgreSQL jest praktyczny.
Przeważnie.
BOOLEAN
BOOLEAN przechowuje wartości true albo false.
Przykład:
available BOOLEAN
Dobre wartości:
true
false
Przykładowa tabela:
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
title VARCHAR(150),
completed BOOLEAN
);
Wstaw dane:
INSERT INTO tasks (title, completed)
VALUES ('Learn PostgreSQL', false);
Później możesz to zaktualizować:
UPDATE tasks
SET completed = true
WHERE title = 'Learn PostgreSQL';
BOOLEAN jest idealny dla wartości tak/nie:
- active;
- completed;
- available;
- published;
- verified.
Nie zapisuj tego jako tekst:
yes
no
maybe
sort of
Tam zaczyna się chaos.
Używaj BOOLEAN.
Pozwól bazie danych sobie pomóc.
DATE
DATE przechowuje daty kalendarzowe.
Przykład:
birth_date DATE
Wstaw datę tak:
'1992-10-23'
PostgreSQL lubi format:
YYYY-MM-DD
Przykładowa tabela:
CREATE TABLE events (
id SERIAL PRIMARY KEY,
title VARCHAR(150),
event_date DATE
);
Wstaw dane:
INSERT INTO events (title, event_date)
VALUES ('PostgreSQL Practice', '2026-05-03');
Daty powinny być datami.
Nie tekstem.
Nie losowymi stringami.
Nie “następny piątek może”.
PostgreSQL może dobrze pracować z datami tylko wtedy, gdy przechowujesz je jako daty.
Szokujące.
Ale prawdziwe.
NUMERIC
NUMERIC przechowuje dokładne liczby dziesiętne.
To przydatne dla pieniędzy.
Przykład:
price NUMERIC(10, 2)
To oznacza:
Maksymalnie 10 cyfr łącznie, z 2 cyframi po przecinku.
Przykładowe wartości:
49.99
100.00
1250.50
Przykładowa tabela:
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
title VARCHAR(150),
price NUMERIC(10, 2)
);
Wstaw dane:
INSERT INTO courses (title, price)
VALUES ('PostgreSQL Basics', 49.99);
Dla cen NUMERIC zwykle jest lepszy niż INTEGER.
Chyba że przechowujesz centy jako liczby całkowite.
To też jest poprawne podejście.
Ale dla początkujących NUMERIC(10, 2) jest łatwe do zrozumienia.
Pieniądze zasługują na precyzję.
Szczególnie kiedy wychodzą z twojego konta.
SERIAL
SERIAL tworzy automatycznie rosnącą liczbę całkowitą.
Przykład:
id SERIAL PRIMARY KEY
To oznacza, że PostgreSQL automatycznie generuje ID.
Przykład:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
Wstaw dane bez id:
INSERT INTO students (name)
VALUES ('Anna');
PostgreSQL automatycznie da Annie ID.
Potem kolejny wiersz dostaje następne ID.
I tak dalej.
Bardzo przydatne.
Nie zarządzaj ID ręcznie, jeśli PostgreSQL może zrobić to za ciebie.
Życie już jest skomplikowane.
Niech baza danych liczy.
Czym Są Ograniczenia?
Ograniczenia to reguły dla danych w tabeli.
Mówią PostgreSQL:
Ta wartość jest wymagana.
Ta wartość musi być unikalna.
Ta wartość musi spełniać warunek.
Ta wartość ma wartość domyślną.
Popularne ograniczenia:
PRIMARY KEY;NOT NULL;UNIQUE;DEFAULT;CHECK.
Ograniczenia robią tabele bezpieczniejsze.
Zatrzymują złe dane, zanim wejdą do tabeli.
Pomyśl o ograniczeniach jak o zasadach tabeli.
Na przykład:
Bez pustych imion.
Bez zduplikowanych emaili.
Bez ujemnych cen.
Bez niemożliwego wieku.
Bardzo rozsądnie.
PostgreSQL jest surowy.
Ale tutaj surowość jest dobra.
NOT NULL
NOT NULL oznacza, że kolumna jest wymagana.
Przykład:
name VARCHAR(100) NOT NULL
To oznacza, że każdy wiersz musi mieć imię.
Przykładowa tabela:
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150)
);
To działa:
INSERT INTO customers (name, email)
VALUES ('Anna', 'anna@example.com');
To nie działa:
INSERT INTO customers (email)
VALUES ('no-name@example.com');
Bo name jest wymagane.
Dobrze.
Żadnych tajemniczych klientów bez imienia.
To nie baza danych szpiegów.
Prawdopodobnie.
UNIQUE
UNIQUE oznacza, że wartości w kolumnie nie mogą się powtarzać.
Bardzo przydatne dla emaili.
Przykład:
email VARCHAR(150) UNIQUE
Tabela:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) UNIQUE
);
Wstaw pierwszego użytkownika:
INSERT INTO users (name, email)
VALUES ('Anna', 'anna@example.com');
To działa.
Spróbuj wstawić kolejnego użytkownika z tym samym emailem:
INSERT INTO users (name, email)
VALUES ('Another Anna', 'anna@example.com');
PostgreSQL to odrzuci.
Bo email musi być unikalny.
To chroni twoje dane.
Bez UNIQUE zduplikowane emaile mogą stworzyć problemy z logowaniem, kontami i bólem głowy.
Ból głowy od bazy danych nie jest zabawny.
Nosi ciężkie buty.
DEFAULT
DEFAULT daje kolumnie wartość, kiedy nie podasz żadnej wartości.
Przykład:
active BOOLEAN DEFAULT true
Tabela:
CREATE TABLE subscribers (
id SERIAL PRIMARY KEY,
email VARCHAR(150) UNIQUE NOT NULL,
active BOOLEAN DEFAULT true
);
Wstaw bez active:
INSERT INTO subscribers (email)
VALUES ('reader@example.com');
Teraz sprawdź:
SELECT * FROM subscribers;
Kolumna active powinna mieć true.
PostgreSQL użył wartości domyślnej.
Wartości domyślne są przydatne, kiedy większość wierszy powinna zaczynać z tą samą wartością.
Na przykład:
active DEFAULT true;completed DEFAULT false;published DEFAULT false;created_at DEFAULT CURRENT_DATE.
Dobre wartości domyślne zmniejszają powtarzający się kod.
A powtarzający się kod to miejsce, gdzie małe bugi budują gniazda.
CHECK
CHECK tworzy regułę, którą wartości muszą spełniać.
Przykład:
price NUMERIC(10, 2) CHECK (price >= 0)
To oznacza, że cena nie może być ujemna.
Tabela:
CREATE TABLE store_products (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price NUMERIC(10, 2) CHECK (price >= 0)
);
To działa:
INSERT INTO store_products (name, price)
VALUES ('Mouse', 25.00);
To nie działa:
INSERT INTO store_products (name, price)
VALUES ('Magic Refund Product', -10.00);
PostgreSQL to odrzuci.
Dobrze.
Ujemne ceny mogą istnieć w księgowości.
Ale nie w tej tabeli.
Baza danych chroni regułę.
Bardzo poważnie.
Bardzo pomocnie.
CHECK z Wiekiem
Inny przykład:
age INTEGER CHECK (age >= 0)
To oznacza, że wiek nie może być ujemny.
Tabela:
CREATE TABLE people (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER CHECK (age >= 0)
);
To działa:
INSERT INTO people (name, age)
VALUES ('Anna', 22);
To nie działa:
INSERT INTO people (name, age)
VALUES ('Time Traveler', -5);
PostgreSQL odmawia.
Dobrze.
Jeśli potrzebujesz podróżników w czasie, zrób osobną tabelę.
Może.
Łączenie Ograniczeń
Możesz połączyć kilka ograniczeń w jednej tabeli.
Przykład:
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)
);
Ta tabela ma wiele reguł:
idjest primary key;namejest wymagane;emailjest wymagany;emailmusi być unikalny;activedomyślnie matrue;agenie może być ujemny.
To znacznie bezpieczniejsze niż tabela bez reguł.
Tabela bez ograniczeń akceptuje za dużo.
Jest zbyt uprzejma.
Bazy danych nie powinny być zbyt uprzejme.
Powinny chronić dane.
Jak poważny bramkarz w klubie informacji.
Stwórz Bezpieczniejszą Tabelę Products
Stwórzmy lepszą tabelę produktów.
Najpierw usuń starą, jeśli trzeba:
DROP TABLE IF EXISTS safe_products;
Teraz utwórz:
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
);
Ta tabela ma lepsze reguły:
namejest wymagane;categoryma wartość domyślną;pricenie może być ujemny;availabledomyślnie matrue.
Wstaw dane:
INSERT INTO safe_products (name, price)
VALUES ('Laptop', 900.00);
Sprawdź:
SELECT * FROM safe_products;
Powinieneś zobaczyć:
category = General
available = true
PostgreSQL uzupełnił wartości domyślne.
Miło.
Baza danych pomaga.
W końcu.
Przetestuj Reguły
Spróbuj wstawić produkt bez nazwy:
INSERT INTO safe_products (price)
VALUES (10.00);
PostgreSQL powinien odrzucić to, bo name jest NOT NULL.
Spróbuj wstawić ujemną cenę:
INSERT INTO safe_products (name, price)
VALUES ('Broken Product', -5.00);
PostgreSQL powinien odrzucić to przez CHECK.
To dobrze.
Tabela broni się sama.
Tabela, która broni się sama, jest dużo bezpieczniejsza niż tabela, która akceptuje wszystko.
Jak drzwi z zamkiem.
Nie idealne.
Ale lepsze niż zasłona.
Sprawdź Tabelę
Uruchom:
\d safe_products
Powinieneś zobaczyć kolumny, typy, wartości domyślne i ograniczenia.
To przydatna komenda.
Używaj jej często.
Kiedy zapomnisz, jak wygląda tabela, zapytaj PostgreSQL.
On pamięta.
Zawsze pamięta.
Bardzo bazodanowo.
Trochę strasznie.
Typowe Błędy
Używanie TEXT do Wszystkiego
Źle:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT,
age TEXT,
active TEXT
);
Lepiej:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age INTEGER,
active BOOLEAN
);
Używaj poprawnego typu.
Tekst nie jest uniwersalnym rozwiązaniem.
To przydatne narzędzie.
Nie worek na śmieci do storage.
Zapominanie NOT NULL
Źle:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(150)
);
To pozwala tworzyć użytkowników bez imion albo emaili.
Może nie tego chcesz.
Lepiej:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL
);
Jeśli wartość jest wymagana, powiedz to.
PostgreSQL będzie tego pilnować.
Zapominanie UNIQUE dla Emaila
Źle:
email VARCHAR(150)
Lepiej:
email VARCHAR(150) UNIQUE
Jeśli emaile identyfikują użytkowników, zwykle powinny być unikalne.
Zduplikowane emaile są jak dwie osoby z tym samym paszportem.
Możliwe w złym systemie.
Fatalny pomysł.
Pozwalanie na Ujemne Ceny
Źle:
price NUMERIC(10, 2)
Lepiej:
price NUMERIC(10, 2) CHECK (price >= 0)
Jeśli ujemne ceny nie mają sensu, zablokuj je.
Nie ufaj, że przyszły kod zawsze będzie grzeczny.
Przyszły kod piszą przyszli ludzie.
Niebezpieczne.
Praktyka
Stwórz tabelę o nazwie employees.
Powinna mieć:
id;name;email;salary;active;hired_at.
Użyj tych reguł:
namejest wymagane;emailjest wymagany i unikalny;salarynie może być ujemne;activedomyślnie matrue;hired_atjest datą.
Przykład:
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
);
Wstaw 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');
Przeczytaj dane:
SELECT * FROM employees;
Potem przetestuj ograniczenia.
Spróbuj zduplikowanego emaila.
Spróbuj ujemnej pensji.
Spróbuj brakującego imienia.
Pozwól PostgreSQL cię zatrzymać.
O to chodzi.
Mini Wyzwanie
Stwórz tabelę o nazwie courses.
Powinna mieć:
id;title;description;price;published;created_at.
Reguły:
titlejest wymagany;pricenie może być ujemny;publisheddomyślnie mafalse;created_atdomyślnie ma aktualną datę.
Podpowiedź:
created_at DATE DEFAULT CURRENT_DATE
Wstaw przynajmniej trzy kursy.
Potem uruchom:
SELECT * FROM courses;
Spróbuj wstawić kurs bez tytułu.
Spróbuj wstawić kurs z ujemną ceną.
PostgreSQL powinien odrzucić złe dane.
To nie PostgreSQL jest irytujący.
To PostgreSQL jest użyteczny.
Jest różnica.
Czasami.
Podsumowanie
Dzisiaj nauczyłeś się:
- typy danych określają, jaki rodzaj danych przechowuje kolumna;
INTEGERprzechowuje liczby całkowite;VARCHARprzechowuje ograniczony tekst;TEXTprzechowuje długi tekst;BOOLEANprzechowujetruealbofalse;DATEprzechowuje daty;NUMERICprzechowuje precyzyjne wartości dziesiętne;SERIALtworzy automatycznie rosnące ID;- ograniczenia tworzą reguły dla danych;
NOT NULLrobi kolumnę wymaganą;UNIQUEblokuje duplikaty;DEFAULTautomatycznie daje wartość;CHECKsprawdza wartości przez warunek;- dobry design tabel chroni bazę danych.
To duży krok.
Nie tworzysz już tylko tabel.
Tworzysz bezpieczniejsze tabele.
Baza danych nie powinna akceptować bzdur.
Powinna chronić strukturę.
Powinna odrzucać złe dane.
Powinna zatrzymywać bananowe wieki, zduplikowane emaile, ujemne ceny i tajemniczych pustych użytkowników.
PostgreSQL potrafi to robić.
Jeśli dasz mu reguły.
Następna Lekcja
W następnej lekcji nauczymy się filtrować i sortować dane.
Wejdziemy głębiej w:
WHERE;- operatory porównania;
AND;OR;LIKE;ORDER BY;LIMIT.
Bo kiedy masz dane, musisz znaleźć właściwe dane.
Nie wszystkie dane.
Właściwe dane.
Tutaj zapytania zaczynają robić się ciekawe.
I lekko niebezpieczne.