Potwierdzone sprawdzone punkt po punkcie · 2026-11-04
Pomiń nawigację
Materiał edukacyjny · Informatyka Bazy danych · Moduł 01

BAZY DANYCH · INF.03

Model relacyjny i projekt bazy

Zanim napiszesz pierwsze zapytanie, trzeba zrozumieć, jak dane są ułożone. W tym module zamienisz szkic biblioteki na tabele, klucze i relacje, a na końcu odczytasz je w phpMyAdmin.

Tabele, wiersze i encje biblioteki

W szkolnej bibliotece wszystko zaczyna się od kartki i ołówka: kto wypożyczył książkę, kiedy ma ją zwrócić i ile zapłaci za spóźnienie. Kiedy takich zapisów przybywa, zeszyt przestaje wystarczać. Relacyjna baza danych porządkuje te informacje w tabele, w których każdy wiersz opisuje jeden konkretny fakt, a każda kolumna jeden rodzaj informacji.

Model relacyjny opiera się na tabelach. Tabela to zbiór wierszy o tej samej strukturze. Wiersz nazywamy rekordem albo krotką, a kolumnę atrybutem. Każda kolumna ma określoną dziedzinę, czyli zbiór dopuszczalnych wartości: kolumna cena przechowuje liczby z dwoma miejscami po przecinku, kolumna data_urodzenia daty, a tytul tekst. Dzięki temu baza może odrzucić wpis, który nie pasuje do ustalonego porządku.

Encja to osoba, rzecz albo zdarzenie, o którym przechowujemy dane. W bibliotece encjami są uczeń, klasa, książka, autor i wypożyczenie. Encja staje się tabelą, a jej cechy kolumnami. Jeden wiersz tabeli ksiazki opisuje jedną książkę, jeden wiersz tabeli uczniowie jednego ucznia, a jeden wiersz tabeli wypozyczenia jedno konkretne wypożyczenie.

SELECT id, tytul, rok_wydania
FROM ksiazki;

To zapytanie czyta trzy kolumny z tabeli ksiazki. Wynik jest również tabelą: ma nagłówki id, tytul, rok_wydania i tyle wierszy, ile książek znajduje się w bazie. Kolejność wierszy nie jest częścią definicji tabeli. Jeśli nie poprosisz o sortowanie, baza może zwrócić je w dowolnej kolejności, choć w praktyce często są to kolejne wiersze z pliku.

SELECT nazwa, wychowawca
FROM klasy;

Druga tabela pokazuje inną encję. klasy nie przechowuje listy uczniów w jednej komórce. Zamiast tego każdy uczeń w tabeli uczniowie ma numer klasy, który wskazuje odpowiedni wiersz w tabeli klasy. To pozornie mniej wygodne niż jeden arkusz, ale chroni przed powtarzaniem nazwiska wychowawcy przy każdym uczniu i przed błędami, gdy wychowawca się zmieni.

Encja Tabela Przykładowe atrybuty Co opisuje jeden wiersz
Uczeń uczniowie imię, nazwisko, data urodzenia, klasa jedną osobę uczęszczającą do szkoły
Klasa klasy nazwa, wychowawca, rok szkolny jeden oddział w danym roku szkolnym
Książka ksiazki tytuł, kategoria, wydawnictwo, cena, stan jeden tytuł w katalogu biblioteki
Wypożyczenie wypozyczenia uczeń, książka, pracownik, daty, kara, status jedno zdarzenie oddania i zwrotu książki

Przykłady z życia

1. Dziennik lekcyjny. Wychowawca prowadzi listę uczniów, oceny i obecności. To trzy różne zbiory informacji, a nie jedna wielka tabela. Gdy ocena trafia do niewłaściwego ucznia, łatwiej ją poprawić, jeśli każdy uczeń ma swój identyfikator, a ocena wskazuje ten identyfikator.

2. Rejestr wypożyczeń w bibliotece. Pani bibliotekarka zapisuje datę wypożyczenia, termin zwrotu i numer książki. Ten sam uczeń może wypożyczyć kilka książek, a ta sama książka może wracać do biblioteki wielokrotnie. Każde takie zdarzenie to osobny wiersz w tabeli wypozyczenia.

3. Lista zakupów. Na kartce zapisujesz produkt, ilość i cenę. To już mała tabela: kolumny to produkt, ilość i cena, a wiersz to jedna pozycja. Jeśli dopiszesz kolumnę „sklep”, nadal pozostaje to tabela, tylko z innym zestawem atrybutów.

Matematyka: tabelę można potraktować jak zbiór uporządkowanych krotek. Każda kolumna ma swoją dziedzinę, a wiersz jest elementem iloczynu dziedzin. To matematyczne spojrzenie wyjaśnia, dlaczego liczba w wierszu musi należeć do właściwego typu i dlaczego nie mieszamy w jednej kolumnie dat z nazwiskami.

Jak to się łączy…

W tej sekcji poznaliśmy tabelę jako zbiór wierszy i encję jako rzecz, którą ta tabela opisuje. W module 02 zobaczysz, jak taką tabelę utworzyć w phpMyAdmin: wybrać typy kolumn, klucz i silnik InnoDB. W module 05 połączysz tabele zapytaniem JOIN, a w module 09 wykorzystasz je w pełnym scenariuszu egzaminacyjnym.

Informatyczna pracownia: każdy formularz w aplikacji zbiera dane do jakiejś tabeli. Projektant strony z polami „imię”, „klasa” i „e-mail” musi wiedzieć, czy te wartości trafią do jednego wiersza, czy do kilku powiązanych tabel. Dobrze zaprojektowana tabela ułatwia późniejsze wyszukiwanie i chroni przed duplikatami.

Zadanie transferowe 1 — od zeszytu do tabel

Biblioteka prowadzi jeden arkusz, w którym każdy wiersz zawiera: imię i nazwisko ucznia, nazwę klasy, wychowawcę, tytuł książki, autora, datę wypożyczenia i termin zwrotu. Wychowawca i tytuł powtarzają się przy wielu wpisach, a po zmianie wychowawcy trzeba poprawiać wiele komórek. Wskaż co najmniej trzy encje, zaproponuj dla nich tabele i kolumny oraz wyjaśnij, jak połączyć je kluczami. Nie musisz pisać gotowego SQL-a — wystarczy opis projektu.

Pokaż przykładowe rozwiązanie i kryteria

Przykład: wydzielamy tabele klasy (id, nazwa, wychowawca, rok_szkolny), uczniowie (id, imie, nazwisko, klasa_id, data_urodzenia), autorzy (id, imie, nazwisko), ksiazki (id, tytul, kategoria_id, rok_wydania) oraz wypozyczenia (id, uczen_id, ksiazka_id, data_wypozyczenia, termin_zwrotu). Uczeń wskazuje klasę przez klasa_id, wypożyczenie wskazuje ucznia i książkę przez odpowiednie identyfikatory. Autora wiążemy z książką osobną tabelą ksiazki_autorzy, bo jedna książka może mieć kilku autorów, a jeden autor może napisać wiele książek.

Kryteria: (1) pojęcie — uczeń nazywa encje, atrybuty i klucze; (2) podział — wychowawca występuje tylko w tabeli klas, a tytuł tylko w tabeli książek; (3) relacje — opisuje powiązania uczeń–klasa, wypożyczenie–uczeń i wypożyczenie–książka; (4) uzasadnienie — wyjaśnia, że podział usuwa powtarzanie danych i ułatwia aktualizację.

1. W tabeli ksiazki jeden wiersz opisuje przede wszystkim...
1. W tabeli ksiazki jeden wiersz opisuje przede wszystkim...
2. Który element tabeli klasy jest atrybutem, a nie całym wierszem ani tabelą?
2. Który element tabeli klasy jest atrybutem, a nie całym wierszem ani tabelą?
3. Dlaczego dane o klasach i uczniach umieszczamy w dwóch powiązanych tabelach?
3. Dlaczego dane o klasach i uczniach umieszczamy w dwóch powiązanych tabelach?

Klucze: identyfikator, obcy i złożony

Wyobraź sobie dwie uczennice o imieniu Anna Kowalska. Samo imię i nazwisko nie wystarcza, żeby wskazać właściwą osobę. Potrzebujemy numeru, który należy do dokładnie jednej osoby i nigdy się nie powtarza. W bazie danych taką rolę pełni klucz podstawowy, najczęściej kolumna id z liczbami nadawanymi automatycznie.

Klucz podstawowy (ang. primary key) jednoznacznie identyfikuje każdy wiersz tabeli. W tabeli uczniowie jest to id, w tabeli ksiazki również id, a w tabeli klasy — id klasy. Klucz musi być unikalny i nie może być pusty. W schemacie biblioteki wszystkie klucze podstawowe są liczbami całkowitymi bez znaku, z opcją AUTO_INCREMENT, więc baza sama nadaje kolejny numer, gdy dodajemy wiersz.

SELECT id, nazwa, wychowawca
FROM klasy;

Wynik pokazuje pięć wierszy i pięć różnych wartości id. To właśnie dzięki nim można bezpiecznie odwołać się do klasy numer 3, nawet jeśli w przyszłości zmieni się jej nazwa albo wychowawca. Nazwa klasy jest dobrym kandydatem na klucz tylko wtedy, gdy naprawdę nigdy się nie powtarza i nie zmienia. W praktyce wygodniejszy jest sztuczny numer, bo nie zależy od decyzji administracyjnych.

Klucz obcy (ang. foreign key) to kolumna, która wskazuje klucz podstawowy w innej tabeli. W tabeli uczniowie kolumna klasa_id wskazuje klasy.id. Dzięki temu baza może sprawdzić, że nie istnieje uczeń przypisany do klasy numer 99, jeśli takiej klasy nie ma. Klucz obcy nie musi być unikalny: wiele uczniów może należeć do tej samej klasy, więc wartość klasa_id powtarza się w wielu wierszach.

SELECT imie, nazwisko, klasa_id
FROM uczniowie
ORDER BY klasa_id, nazwisko;

To zapytanie pokazuje, jak wygląda relacja jeden-do-wielu po stronie danych. Kolumna klasa_id jest tym samym kluczem obcym w każdym wierszu, ale jej wartości się powtarzają. Powtórzenie nie jest tu błędem — przeciwnie, jest dowodem, że kilka osób należy do jednej klasy. Błędem byłoby natomiast wpisanie numeru klasy, której nie ma w tabeli klasy.

Klucz złożony powstaje z dwóch lub więcej kolumn, które razem muszą być unikalne. W tabeli ksiazki_autorzy para ksiazka_id i autor_id jest unikalna: ta sama książka nie może mieć dwa razy tego samego autora, ale może mieć wielu różnych autorów. Podobnie w tabeli opinie para uczeń–książka jest unikalna, bo jeden uczeń wystawia jednej książce tylko jedną opinię.

SELECT ksiazka_id, autor_id, rola
FROM ksiazki_autorzy
WHERE ksiazka_id = 4
ORDER BY autor_id;

Książka numer 4, „Wiedźmin: Ostatnie życzenie”, ma dwóch autorów: Andrzeja Sapkowskiego jako autora i Marcina Krajewskiego jako współautora. Para kluczy jest różna, więc oba wiersze mogą istnieć. Gdybyśmy próbowali dodać drugi raz tę samą parę, baza odrzuciłaby wpis dzięki ograniczeniu UNIQUE.

Rodzaj klucza Gdzie w bibliotece Co gwarantuje
Podstawowy klasy.id, uczniowie.id, ksiazki.id każdy wiersz ma unikalny, niepusty identyfikator
Obcy uczniowie.klasa_id, wypozyczenia.uczen_id wartość wskazuje istniejący wiersz w tabeli nadrzędnej
Unikalny uczniowie.email, ksiazki.isbn, kategorie.kod dana wartość nie powtarza się w kolumnie
Złożony ksiazki_autorzy (ksiazka_id, autor_id) unikalna jest dopiero cała para wartości
Unikalność a NULL. Kolumna email w tabeli uczniowie jest unikalna, ale dopuszcza NULL. W MySQL kilka wierszy może mieć w tej kolumnie NULL, bo NULL oznacza brak wartości, a nie konkretny napis. To wygodne, gdy nie każdy uczeń podał adres e-mail, ale wymaga ostrożności przy liczeniu i porównywaniu.

Przykłady z życia

1. Numer legitymacji szkolnej. Imię i nazwisko może się powtórzyć, ale numer legitymacji jest przypisany do jednej osoby. To naturalny odpowiednik klucza podstawowego. Gdy uczeń zmienia klasę, numer legitymacji pozostaje ten sam, więc dane w innych tabelach nadal wskazują właściwą osobę.

2. Numer zamówienia w sklepie internetowym. Każde zamówienie ma swój numer, a pozycje zamówienia wskazują ten numer jako klucz obcy. Jedno zamówienie może mieć wiele pozycji, więc numer zamówienia powtarza się w tabeli pozycji — dokładnie tak jak klasa_id w tabeli uczniów.

3. Rejestr książek według ISBN. ISBN identyfikuje wydanie książki, ale biblioteka może mieć kilka egzemplarzy tego samego tytułu. Dlatego w bazie potrzebny jest osobny id egzemplarza, a ISBN jest dodatkowym kluczem unikalnym. Dwa różne egzemplarze mają ten sam ISBN, ale różne id.

Informatyczna pracownia: w aplikacji do wypożyczeń przycisk „zapisz” wysyła do bazy numer ucznia i numer książki. Jeśli program wyśle numer ucznia, który nie istnieje, baza odrzuci rekord dzięki kluczowi obcemu. To znacznie bezpieczniejsze niż poleganie wyłącznie na sprawdzaniu w formularzu, bo formularz można obejść, a ograniczenie w bazie działa zawsze.

Jak to się łączy…

W poprzedniej sekcji dzieliliśmy dane na tabele. Klucz podstawowy i obcy to fundament ich łączenia. W module 02 zobaczysz, jak zdefiniować je w CREATE TABLE i jakie typy dobrać dla kolumn. W module 05 użyjesz kluczy w zapytaniach JOIN, a w module 07 sprawdzisz, co się dzieje z kluczami obcymi przy dodawaniu i usuwaniu danych.

Biuro: w arkuszu kalkulacyjnym często wpisuje się numer klienta obok każdej faktury. To właśnie klucz obcy. Jeśli numer klienta zostanie wpisany z literówką, faktura nie będzie powiązana z właściwą kartoteką — baza danych potrafi taki błąd wychwycić, arkusz zwykle nie.

4. Który klucz pozwala powiązać ucznia z jego klasą?
4. Który klucz pozwala powiązać ucznia z jego klasą?
5. Co gwarantuje unikalna para ksiazka_id i autor_id w tabeli ksiazki_autorzy?
5. Co gwarantuje unikalna para ksiazka_id i autor_id w tabeli ksiazki_autorzy?
6. Kolumna email w tabeli uczniowie ma ograniczenie UNIQUE i dopuszcza NULL. Co się stanie, gdy kilku uczniów nie poda adresu?
6. Kolumna email w tabeli uczniowie ma ograniczenie UNIQUE i dopuszcza NULL. Co się stanie, gdy kilku uczniów nie poda adresu?

Relacje, normalizacja i ERD biblioteki

Tabele nie istnieją w izolacji. Uczeń należy do klasy, książka ma kategorię i wydawnictwo, a wypożyczenie łączy ucznia z książką. Te powiązania nazywamy relacjami. Najczęstsza relacja to jeden-do-wielu: jednej klasie odpowiada wielu uczniów, ale każdy uczeń należy do jednej klasy. W bazie biblioteki widać ją po kluczu obcym klasa_id w tabeli uczniowie.

Podobnie jedna kategoria obejmuje wiele książek, a jedna książka ma jedną kategorię. Relację jeden-do-wielu zapisujemy po stronie „wielu”: kolumna kategoria_id znajduje się w tabeli ksiazki, a nie odwrotnie. Gdybyśmy w tabeli kategorie wpisali listę książek, musielibyśmy upchnąć wiele tytułów w jednej komórce albo dodawać kolejne kolumny, co szybko stałoby się nieczytelne.

SELECT tytul, kategoria_id, wydawnictwo_id
FROM ksiazki
ORDER BY kategoria_id, tytul;

Ten wynik pokazuje same numery, a nie nazwy kategorii i wydawnictw. To celowe: nazwa kategorii jest przechowywana tylko w tabeli kategorie, a nazwa wydawnictwa tylko w tabeli wydawnictwa. Jeśli zmienisz nazwę kategorii, poprawiasz jeden wiersz, a wszystkie książki nadal wskazują właściwy numer. To zasada jednego źródła prawdy.

Nie każdą relację da się przedstawić kluczem obcym w jednej z dwóch tabel. Książka może mieć kilku autorów, a jeden autor może napisać wiele książek. To relacja wiele-do-wielu. Rozwiązujemy ją tabelą pośrednią ksiazki_autorzy, która zawiera parę kluczy: ksiazka_id i autor_id. Podobnie uczeń i książka spotykają się w tabeli wypozyczenia, która dodatkowo przechowuje daty, karę i status — informacje należące do samego zdarzenia, a nie do osoby ani do książki.

ERD biblioteki szkolnej — najważniejsze tabele i relacje klasy id (PK) nazwa wychowawca rok_szkolny uczniowie id (PK) imie, nazwisko klasa_id (FK) data_urodzenia email, aktywny wypozyczenia id (PK) uczen_id (FK) ksiazka_id (FK) pracownik_id (FK) data_wypozyczenia, termin_zwrotu data_zwrotu, kara, status kategorie id (PK) nazwa, kod opis ksiazki id (PK) tytul kategoria_id (FK) wydawnictwo_id (FK) rok_wydania, isbn, cena ksiazki_autorzy id (PK) ksiazka_id (FK) autor_id (FK), rola autorzy id (PK) imie, nazwisko kraj, rok_urodzenia wydawnictwa id (PK) nazwa, miasto telefon 1 N 1 N 1 N 1 N 1 N 1 N 1 N PK — klucz podstawowy, FK — klucz obcy. Tabela wypozyczenia łączy uczniów i książki, a ksiazki_autorzy — książki i autorów.
Uproszczony ERD: prostokąty to tabele, strzałki pokazują kierunek powiązania, a liczby 1 i N — jedną i wiele stron relacji. Tabela wypozyczenia jest jednocześnie zdarzeniem i połączeniem dwóch encji. Dla czytelności pominęliśmy tabelę pracownicy, do której również prowadzi klucz obcy.

Normalizacja to proces porządkowania tabel tak, aby dane nie były przechowywane wielokrotnie i aby nie powstały sprzeczności. Pierwsza postać normalna wymaga wartości atomowych: w kolumnie telefon wpisujemy jeden numer, a nie listę numerów rozdzielonych przecinkami. Druga postać normalna zakazuje zależności od tylko części klucza złożonego. W tabeli ksiazki_autorzy rola autora zależy od pary książka–autor, a nie od samego numeru książki, więc jest poprawnie umieszczona.

Trzecia postać normalna usuwa zależności przechodnie. Gdyby tabela ksiazki zawierała także nazwa_kategorii i miasto_wydawnictwa, nazwa kategorii zależałaby od kategoria_id, a nie bezpośrednio od książki. Zmiana nazwy kategorii wymagałaby poprawienia wielu wierszy. Dlatego trzymamy tylko klucze obce, a nazwy i miasta w tabelach słownikowych. To nie jest „nadmiar tabel”, lecz sposób na uniknięcie nadmiaru błędów.

Przykłady z życia

1. Plan lekcji. Jeden nauczyciel uczy wielu klas, a jedna klasa ma wielu nauczycieli. Gdyby plan zapisywać w jednej tabeli z powtarzającą się nazwą klasy przy każdym nauczycielu, literówka w nazwie rozbiłaby porządek. Tabela pośrednia „nauczyciel–klasa–przedmiot” rozwiązuje ten problem podobnie jak ksiazki_autorzy.

2. Zamówienie w stołówce. Jedno zamówienie może zawierać kilka dań, a jedna potrawa może wystąpić w wielu zamówieniach. Potrzebna jest tabela pozycji zamówienia z kluczami zamowienie_id i danie_id. Sam numer zamówienia w tabeli dań nie wystarczy, bo danie nie należy do jednego zamówienia.

3. Katalog biblioteczny. Czytelnik szuka książki po autorze, a autor może mieć wiele książek. Ekran katalogu pokazuje autora i tytuły, ale w bazie są to dwie tabele połączone tabelą ksiazki_autorzy. Dzięki temu nie trzeba wpisywać nazwiska autora przy każdym tytule.

Matematyka: relację można opisać jak funkcję. Numer klasy prowadzi do jednego wychowawcy, numer książki do jednej kategorii. Normalizacja pilnuje, aby każda informacja zależała od właściwego klucza, a nie od przypadkowej kopii. To ta sama zasada, którą w matematyce nazywamy jednoznacznością przyporządkowania.

Jak to się łączy…

W poprzedniej sekcji poznaliśmy klucze. Relacje i normalizacja pokazują, jak ułożyć z nich całą bazę. Wrócą one w module 04, gdy będziesz liczyć książki w kategoriach, oraz w module 05, gdzie JOIN zamieni numery kluczy na czytelne nazwy. W module 07 zobaczysz, jak dodawanie i usuwanie danych respektuje klucze obce, a w module 09 cały projekt wykorzystasz w zadaniu egzaminacyjnym.

Geografia: mapa to też zestaw warstw i powiązań. Województwo zawiera powiaty, powiat gminy, a gmina miejscowości. Zamiast wpisywać nazwę województwa przy każdej miejscowości, trzymamy identyfikatory i łączymy warstwy — dokładnie jak tabele w relacyjnej bazie.

Zadanie transferowe 2 — ERD kącika gier

Biblioteka otwiera kącik gier planszowych. Każda gra ma tytuł, wydawcę, rok wydania i liczbę graczy. Gra może mieć kilku autorów, a jeden autor może tworzyć wiele gier. Uczeń może wypożyczyć wiele gier, a jedna gra może być wypożyczana wielokrotnie. Zaprojektuj co najmniej cztery tabele, wskaż klucze podstawowe i obce, opisz relacje i wyjaśnij, dlaczego nie umieścisz listy autorów w jednej kolumnie tabeli gier. Możesz narysować diagram odręcznie lub opisać go słowami.

Pokaż przykładowe rozwiązanie i kryteria

Przykład: tabele gry (id, tytul, wydawca_id, rok_wydania, liczba_graczy), wydawcy (id, nazwa, miasto), autorzy (id, imie, nazwisko), gry_autorzy (id, gra_id, autor_id) oraz wypozyczenia_gier (id, uczen_id, gra_id, data_wypozyczenia, data_zwrotu). Relacja gra–autor jest wiele-do-wielu, więc wymaga tabeli pośredniej. Wypożyczenie wskazuje ucznia i grę, a daty opisują konkretne zdarzenie, nie samą grę.

Kryteria: (1) encje — wyodrębniono gry, autorów, wydawców i wypożyczenia; (2) klucze — każda tabela ma klucz podstawowy, a tabele powiązane mają klucze obce; (3) relacje — poprawnie opisano wiele-do-wielu i jeden-do-wielu; (4) normalizacja — uczeń uzasadnia, że lista autorów w jednej komórce łamie wartość atomową i utrudnia wyszukiwanie.

7. Jaki typ relacji występuje między tabelami klasy i uczniowie?
7. Jaki typ relacji występuje między tabelami klasy i uczniowie?
8. Który zapis łamie trzecią postać normalną?
8. Który zapis łamie trzecią postać normalną?
9. Po co w bazie biblioteki istnieje tabela ksiazki_autorzy?
9. Po co w bazie biblioteki istnieje tabela ksiazki_autorzy?

Ćwiczenia SQL

Zadania do samodzielnego wykonania w edytorze SQL.