Lekcja 5. Normalizacja bazy danych
ŚredniPo 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
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
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_.gzi import nie przejdzie, zmień nazwę pliku nasklep_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.
- Wskaż powtarzające się dane w tabeli źródłowej.
- Podziel dane na co najmniej trzy tabele.
- Wskaż klucz główny każdej tabeli.
- Wskaż klucze obce po podziale.
- Doprowadź dane do 1NF.
- Wyjaśnij, co zmienić, aby baza spełniała 2NF.
- Wyjaśnij, co zmienić, aby baza spełniała 3NF.
- Zapisz przykładowe CREATE TABLE po normalizacji.
- Zapisz przykładowe INSERT dla każdej tabeli.
- Napisz JOIN odtwarzający pierwotny widok danych.
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_.gzi import nie przejdzie, zmień nazwę pliku nasklep_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.
- Wskaż powtarzające się dane w tabeli źródłowej.
- Podziel dane na co najmniej trzy tabele.
- Wskaż klucz główny każdej tabeli.
- Wskaż klucze obce po podziale.
- Doprowadź dane do 1NF.
- Wyjaśnij, co zmienić, aby baza spełniała 2NF.
- Wyjaśnij, co zmienić, aby baza spełniała 3NF.
- Zapisz przykładowe CREATE TABLE po normalizacji.
- Zapisz przykładowe INSERT dla każdej tabeli.
- Napisz JOIN odtwarzający pierwotny widok danych.
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_.gzi import nie przejdzie, zmień nazwę pliku nasklep_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.
- Wskaż powtarzające się dane w tabeli źródłowej.
- Podziel dane na co najmniej trzy tabele.
- Wskaż klucz główny każdej tabeli.
- Wskaż klucze obce po podziale.
- Doprowadź dane do 1NF.
- Wyjaśnij, co zmienić, aby baza spełniała 2NF.
- Wyjaśnij, co zmienić, aby baza spełniała 3NF.
- Zapisz przykładowe CREATE TABLE po normalizacji.
- Zapisz przykładowe INSERT dla każdej tabeli.
- 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.