Schemat bazy danych (database schema) to logiczna mapa tego, jak Twoje dane są poukładane: jakie istnieją tabele, jakie mają kolumny i typy, jak tabele łączą się ze sobą relacjami (klucze obce), plus dodatki w stylu widoków, indeksów i ograniczeń (constraints). Mówiąc po ludzku: to plan budynku, zanim wprowadzisz lokatorów. Sam schemat nie zawiera danych — opisuje ich strukturę i reguły, których dane muszą się trzymać.
Warto rozróżnić dwa znaczenia słowa „schema”, bo początkujący się na tym wykładają. Pierwsze to ogólny projekt struktury. Drugie to konkretny obiekt w bazie — w PostgreSQL czy SQL Server schema jest też przestrzenią nazw (namespace), która grupuje tabele, np. public.users albo sales.invoices. To samo słowo, dwa konteksty.
Do czego to służy
Schemat pełni rolę kontraktu między bazą a aplikacją. Definiuje, że kolumna email jest tekstem i musi być unikalna, że user_id w tabeli zamówień musi wskazywać na istniejącego użytkownika, a price nie może być ujemne. Dzięki temu baza sama pilnuje spójności danych, zanim zdąży narobić bałaganu Twój kod aplikacji.
Schemat zmienia się w czasie — dodajesz kolumny, tabele, indeksy. Tym zarządza się przez migracje: ponumerowane skrypty SQL trzymane w repozytorium, dzięki którym każdy programista i każdy serwer mają identyczną strukturę bazy. Wersjonowanie schematu jest równie ważne co wersjonowanie kodu.
Przykład z praktyki
Załóżmy sklep w PostgreSQL. Tworzysz tabelę użytkowników i powiązaną tabelę zamówień:
CREATE TABLE users (id SERIAL PRIMARY KEY, email TEXT UNIQUE NOT NULL);CREATE TABLE orders (id SERIAL PRIMARY KEY, user_id INT REFERENCES users(id), total NUMERIC(10,2) CHECK (total >= 0));
Klauzula REFERENCES to relacja jeden-do-wielu: jeden użytkownik, wiele zamówień. UNIQUE, NOT NULL i CHECK to constraints, które są częścią schematu. Strukturę istniejącej bazy podejrzysz w psql komendą \d orders, a w GUI typu DBeaver czy DataGrip — jako diagram ERD, który automatycznie rysuje tabele i strzałki między nimi.
Częste błędy i mity
- Brak indeksów na kluczach obcych — relacja działa, ale zapytania z
JOINpotrafią zwolnić dramatycznie. Indeks to część schematu, nie luksus. - Ręczne zmiany na produkcji — „dodam tylko jedną kolumkę przez kliknięcie w narzędziu”. Tak rodzi się dryf schematu, gdzie produkcja różni się od repozytorium i nikt nie wie dlaczego. Zawsze przez migracje.
- Mit, że NoSQL nie ma schematu — bazy dokumentowe jak MongoDB są schema-less na poziomie silnika, ale schemat i tak istnieje — tyle że niejawnie, w Twoim kodzie. Niepilnowany potrafi boleć mocniej.
Pojęcia powiązane: model relacyjny, normalizacja, klucz główny i obcy, diagram ERD, migracje, DDL (CREATE/ALTER), constraints, indeksy.