Normalizację baz danych można streścić jednym zdaniem: „Tę samą informację przechowuj tylko w jednym miejscu.” Sposób, by zrobić to systematycznie, to 1NF → 2NF → 3NF.

Dlaczego to ważne? — Jeśli ta sama informacja jest rozrzucona po wielu wierszach, wystarczy poprawić tylko jeden z nich i pominąć resztę, a dane staną się sprzeczne. To nazywamy anomalią aktualizacji. Poniżej możesz zobaczyć to na własne oczy.

Update Anomaly — Try It

Prof.A moved to Room 502. Click the cell to update it. Notice: you have to change every row — miss one and the data contradicts itself.

Before (unnormalized)
studentcourseinstructorofficegrade
S1 KimMATH101Prof.ARoom 301 ← clickA
S1 KimCS102Prof.BRoom 405B+
S2 LeeCS102Prof.BRoom 405A
S3 ParkMATH101Prof.ARoom 301 ← clickB
0/2 updated
After (3NF)
Instructorsinstructor_idinstructor_office
Prof.ARoom 502
Prof.BRoom 405
In 3NF, you update exactly 1 row in the Instructors table. Done.

Jeśli zmienił się pokój laboratorium Prof.A, to w nienormalizowanej tabeli trzeba ręcznie poprawić oba wiersze. Jeśli choć jeden zostanie pominięty, pojawi się sprzeczność: „Prof.A jest jednocześnie w Room 301 i Room 502”. W tabelach 3NF wystarczy zmienić dokładnie 1 wiersz i gotowe.

To właściwie cała idea normalizacji — cała reszta to tylko reguły pomagające zdecydować, „które kolumny gdzie umieścić, żeby dana informacja była przechowywana tylko raz”.

Zależność funkcyjna — kryterium normalizacji

Normalizacja sprawdza, „od czego zależy ta kolumna”. To właśnie zależność funkcyjna.

Na przykład student_id → student_name oznacza: „jeśli znamy ID studenta, to jego imię i nazwisko są już wyznaczone”.

Na diagramie poniżej zwróć uwagę na kolory strzałek:

  • zielony = zależność od całego klucza (poprawnie)
  • żółty = zależność tylko od części klucza (zależność częściowa → naruszenie 2NF)
  • czerwona linia przerywana = zależność przez kolumnę niekluczową (zależność przechodnia → naruszenie 3NF)
Functional Dependencies at a Glance

Enrollment(student_id, course_id, student_name, course_title, instructor_id, instructor_office, grade)

student_idPrimary Keycourse_idPrimary Keystudent_namecourse_titleinstructor_idinstructor_officegrade
Full dependency (on entire key)Partial dependency (on part of key)Transitive dependency (via non-key)

Usunięcie żółtych i czerwonych strzałek = podzielenie tabeli = normalizacja.

1NF → 2NF → 3NF na jednym przykładzie

Kliknij poniżej i zobacz krok po kroku, jak tabela jest dzielona na etapy. Czerwone komórki oznaczają: „tej kolumny nie powinno tu być”.

Normalization Step-by-Step
Everything in one table. Multiple values in one cell.
Enrollment
student_id 🔑student_namecoursesgrades
S1KimMATH101, CS102A, B+
S2LeeCS102A
S3ParkMATH101, CS102, PHY201B, A, A-
Problem: courses column has multiple values crammed into one cell.
Fix: Split into one row per student-course pair.

1NF: jedna wartość w jednej komórce

Jeśli w jednej komórce wpiszesz kilka wartości, np. MATH101, CS102, to nie da się tego sensownie wyszukiwać ani robić JOIN.

Reguła: każda komórka musi być atomowa, czyli zawierać tylko jedną wartość.

Kolumny takie jak phone1, phone2, phone3 mają ten sam problem — po prostu ukrywają wartości w nazwach kolumn.

2NF: usunięcie zależności częściowych

W tabeli z kluczem złożonym (student_id, course_id) kolumna student_name zależy tylko od student_id. Nie zależy więc od całego klucza, tylko od jego części — to właśnie częściowa zależność funkcyjna.

Reguła: każda kolumna niekluczowa musi zależeć od całego klucza.

Jeśli występuje zależność częściowa, taką kolumnę należy wydzielić do osobnej tabeli.

A jeśli klucz składa się tylko z jednej kolumny? Wtedy zależność częściowa jest niemożliwa, więc 1NF automatycznie oznacza też 2NF.

3NF: usunięcie zależności przechodnich

W tabeli Courses kolumna instructor_office nie zależy bezpośrednio od course_id (klucza). Zależność przebiega ścieżką course_id → instructor_id → instructor_office — czyli kolumna niekluczowa zależy od innej kolumny niekluczowej. To jest zależność przechodnia.

Reguła: kolumny niekluczowe powinny zależeć wyłącznie od klucza. Nie mogą zależeć przez inną kolumnę niekluczową.

Rozwiązanie: przenieść instructor_office do tabeli Instructors.

Zamiast wkuwania — jedno pytanie

„Każdy atrybut niekluczowy powinien zależeć od klucza, całego klucza i tylko klucza.”

To zdanie mówi wszystko:

  • od klucza = 1NF (informacja musi dać się zidentyfikować przez klucz)
  • od całego klucza = 2NF (zależność od całego klucza, a nie tylko jego części)
  • tylko od klucza = 3NF (bez przechodzenia przez kolumny niekluczowe)

Jeśli na egzaminie pojawi się zadanie o normalizacji, zadaj tylko jedno pytanie: „Od czego zależy ta kolumna? Od całego klucza, od części klucza, czy od kolumny niekluczowej?”

Częste błędy

„Na 3NF się kończy” — 3NF to dobry punkt startowy, ale nie zawsze koniec. Czasem potrzebna jest bardziej rygorystyczna postać, jak BCNF, a czasem dla wydajności celowo stosuje się denormalizację.

„Im więcej tabel, tym lepiej” — celem normalizacji nie jest zwiększanie liczby tabel, tylko dopilnowanie, by „każda tabela odpowiadała za jeden rodzaj informacji”. Jeśli dzielisz bez powodu (czyli bez uzasadnienia w zależnościach), tylko komplikujesz JOIN.

„W NoSQL normalizacja nie jest potrzebna” — normalizacja to termin związany z relacyjnymi DB, ale problem „spójności zduplikowanych danych” istnieje w każdym rodzaju bazy. Nawet przy denormalizacji trzeba wiedzieć, „z czego się rezygnuje”.

Sprawdź to samodzielnie

Wybierz jedną tabelę ze swojego projektu i:

  1. Zapisz, jaki jest jej klucz.
  2. Sprawdź, czy każda kolumna niekluczowa zależy od całego klucza, czy tylko od jego części. → Jeśli od części, to naruszenie 2NF.
  3. Sprawdź, czy jakaś kolumna niekluczowa zależy od innej kolumny niekluczowej. → Jeśli tak, to naruszenie 3NF.

Te 3 kroki wystarczą, by wychwycić większość problemów z normalizacją.

Potrzebujesz pomocy z zadaniem?

Prześlij pytanie i otrzymaj zweryfikowane rozwiązanie krok po kroku w kilka sekund.

Otwórz GPAI Solver →