Dataczwartek, 13 sierpnia 2026 Czas19:13:07
← Bazy danych i SQL

Lekcja 5. Normalizacja bazy danych

Średni

Po co się tego uczymy?

Źle zaprojektowana baza danych potrafi się "zepsuć" sama z siebie — wystarczy, że ten sam adres klienta jest zapisany w dziesięciu różnych zamówieniach, a przy zmianie adresu ktoś zaktualizuje tylko dziewięć z nich. Normalizacja to zestaw reguł, które zapobiegają takiemu bałaganowi.

Teoria

Normalizacja to proces porządkowania struktury bazy danych tak, żeby każda informacja była zapisana tylko raz, w jednym miejscu. Im wyższa "postać normalna" (Normal Form, NF), tym mniej duplikacji danych.

Trzy podstawowe postacie normalne (w uproszczeniu, na poziomie technikum):
- 1NF (pierwsza postać normalna) — każda komórka w tabeli przechowuje tylko jedną, niepodzielną wartość (żadnych list w jednej kolumnie, np. "jabłko, gruszka, banan" w jednym polu).
- 2NF (druga postać normalna) — tabela jest w 1NF i każda kolumna, która nie jest kluczem, zależy od CAŁEGO klucza głównego, a nie tylko od jego części.
- 3NF (trzecia postać normalna) — tabela jest w 2NF i żadna kolumna niebędąca kluczem nie zależy od innej kolumny niebędącej kluczem (czyli nie ma "zależności przechodnich").

W praktyce najważniejszy sygnał, że baza wymaga normalizacji, to powtarzające się dane — jeśli widzisz, że ta sama informacja (np. adres klienta) pojawia się w wielu wierszach tabeli zamówień, to znak, że trzeba ją wydzielić do osobnej tabeli.

Schemat

PRZED normalizacją Zamowienia id, produkt, ilosc, imie_klienta, adres_klienta ← powtarza się w każdym wierszu tego samego klienta! PO normalizacji Klienci id_klienta (PK) imie, adres Zamowienia id_klienta (FK) produkt, ilosc Dane klienta zapisane raz, w jednym miejscu — zmiana adresu wymaga edycji tylko jednego wiersza, zamiast poprawiania go we wszystkich zamówieniach

Przykład z życia

System zamówień, w którym imię i adres klienta są zapisane bezpośrednio w każdym zamówieniu. Jeśli klient złoży 20 zamówień, jego adres jest powielony 20 razy. Gdy się przeprowadzi, trzeba by poprawić 20 wierszy — a jeśli ktoś zapomni poprawić jeden, dane w bazie zaczynają sobie przeczyć.

Kod (SQL)

-- PRZED normalizacją: jedna szeroka tabela z powtarzającymi się danymi klienta

CREATE TABLE Zamowienia_niezormalizowane (
    id_zamowienia INT PRIMARY KEY,
    produkt VARCHAR(100),
    ilosc INT,
    imie_klienta VARCHAR(50),   -- powtarza się w każdym zamówieniu tego klienta

    adres_klienta VARCHAR(150)  -- powtarza się w każdym zamówieniu tego klienta

);

-- PO normalizacji: dane klienta wydzielone do osobnej tabeli

CREATE TABLE Klienci (
    id_klienta INT AUTO_INCREMENT PRIMARY KEY,
    imie VARCHAR(50) NOT NULL,
    adres VARCHAR(150) NOT NULL
);

CREATE TABLE Zamowienia (
    id_zamowienia INT AUTO_INCREMENT PRIMARY KEY,
    produkt VARCHAR(100) NOT NULL,
    ilosc INT NOT NULL,
    id_klienta INT NOT NULL,
    FOREIGN KEY (id_klienta) REFERENCES Klienci(id_klienta)
);

Komentarz i wyjaśnienie kodu

W wersji "przed" dane klienta (imie_klienta, adres_klienta) są wpisane bezpośrednio w tabeli zamówień — jeśli klient złoży 5 zamówień, jego adres pojawi się w bazie 5 razy. W wersji "po" dane klienta trafiają do osobnej tabeli Klienci, a tabela Zamowienia trzyma tylko id_klienta jako klucz obcy. Adres klienta jest teraz zapisany dokładnie raz — zmiana adresu to jedna aktualizacja w jednym miejscu, a nie edycja dziesięciu wierszy.

Ćwiczenie samodzielne

Weź tabelę Zamowienia_niezormalizowane z kodu powyżej i samodzielnie "przepisz na kartce", jak wyglądałyby dane w tabelach Klienci i Zamowienia po normalizacji, dla dwóch przykładowych zamówień tego samego klienta.

Zadania do pracy własnej

  1. Zadanie 1. Normalizacja biblioteki

    Uwaga przed importem: plik z bazą jest spakowany jako .gz. phpMyAdmin w XAMPP przyjmuje takie pliki bez rozpakowywania. Jeżeli po pobraniu nazwa wygląda np. sklep_muzyczny.sql_.gz i import nie przejdzie, zmień nazwę pliku na sklep_muzyczny.sql.gz, a potem wybierz go w zakładce Importuj.

    Baza do pracy: Biblioteka szkolna (.sql.gz). Zaimportuj spakowany plik SQL w XAMPP/phpMyAdmin, a następnie wykonaj zapytania.

    1. Wskaż powtarzające się dane w tabeli źródłowej.
    2. Podziel dane na co najmniej trzy tabele.
    3. Wskaż klucz główny każdej tabeli.
    4. Wskaż klucze obce po podziale.
    5. Doprowadź dane do 1NF.
    6. Wyjaśnij, co zmienić, aby baza spełniała 2NF.
    7. Wyjaśnij, co zmienić, aby baza spełniała 3NF.
    8. Zapisz przykładowe CREATE TABLE po normalizacji.
    9. Zapisz przykładowe INSERT dla każdej tabeli.
    10. Napisz JOIN odtwarzający pierwotny widok danych.
  2. Zadanie 2. Normalizacja sklepu 2P

    Uwaga przed importem: plik z bazą jest spakowany jako .gz. phpMyAdmin w XAMPP przyjmuje takie pliki bez rozpakowywania. Jeżeli po pobraniu nazwa wygląda np. sklep_muzyczny.sql_.gz i import nie przejdzie, zmień nazwę pliku na sklep_muzyczny.sql.gz, a potem wybierz go w zakładce Importuj.

    Baza do pracy: Sklep muzyczny 2P (.sql.gz). Zaimportuj spakowany plik SQL w XAMPP/phpMyAdmin, a następnie wykonaj zapytania.

    1. Wskaż powtarzające się dane w tabeli źródłowej.
    2. Podziel dane na co najmniej trzy tabele.
    3. Wskaż klucz główny każdej tabeli.
    4. Wskaż klucze obce po podziale.
    5. Doprowadź dane do 1NF.
    6. Wyjaśnij, co zmienić, aby baza spełniała 2NF.
    7. Wyjaśnij, co zmienić, aby baza spełniała 3NF.
    8. Zapisz przykładowe CREATE TABLE po normalizacji.
    9. Zapisz przykładowe INSERT dla każdej tabeli.
    10. Napisz JOIN odtwarzający pierwotny widok danych.
  3. Zadanie 3. Normalizacja szkoły

    Uwaga przed importem: plik z bazą jest spakowany jako .gz. phpMyAdmin w XAMPP przyjmuje takie pliki bez rozpakowywania. Jeżeli po pobraniu nazwa wygląda np. sklep_muzyczny.sql_.gz i import nie przejdzie, zmień nazwę pliku na sklep_muzyczny.sql.gz, a potem wybierz go w zakładce Importuj.

    Baza do pracy: Szkoła relacje (.sql.gz). Zaimportuj spakowany plik SQL w XAMPP/phpMyAdmin, a następnie wykonaj zapytania.

    1. Wskaż powtarzające się dane w tabeli źródłowej.
    2. Podziel dane na co najmniej trzy tabele.
    3. Wskaż klucz główny każdej tabeli.
    4. Wskaż klucze obce po podziale.
    5. Doprowadź dane do 1NF.
    6. Wyjaśnij, co zmienić, aby baza spełniała 2NF.
    7. Wyjaśnij, co zmienić, aby baza spełniała 3NF.
    8. Zapisz przykładowe CREATE TABLE po normalizacji.
    9. Zapisz przykładowe INSERT dla każdej tabeli.
    10. Napisz JOIN odtwarzający pierwotny widok danych.

Typowe błędy

Częsty błąd to przesadna normalizacja — rozbijanie danych na tak wiele małych tabel, że proste zapytanie wymaga pięciu JOIN-ów i staje się nieczytelne. Drugi błąd to mylenie 2NF z 3NF — 2NF dotyczy zależności od CAŁEGO klucza głównego (ważne głównie przy kluczach złożonych z kilku kolumn), a 3NF dotyczy zależności między kolumnami, które same nie są kluczem. Trzeci błąd: normalizowanie "na siłę" tam, gdzie dane i tak się nie powtarzają — normalizacja ma sens tam, gdzie faktycznie widać duplikację.

Nawiązanie do egzaminu zawodowego

Postacie normalne są wprost wymienione w efekcie kształcenia INF.03.4.1 ("rozpoznaje postacie normalne baz danych") — na egzaminie pisemnym może pojawić się pytanie o rozpoznanie, w jakiej postaci normalnej jest dana tabela, albo o wskazanie problemu wynikającego z braku normalizacji.