ITBlog

IT Blog w tematach różnych...

  • O blogu…
  • Edukacja
    • Moodle – stare
    • Moodle2
    • Testy
  • Firma

Bazy danych – Wstęp do normalizacji

Napisane przez Igor Brzeżek on 2 listopada 2025
Napisane w: Bazy danych.

Contents
  1. Proces normalizacji bazy danych: krok po kroku
  2. Stan wyjściowy: tabela nieznormalizowana
  3. Struktura tabeli `czytelnicy_archiwum`
  4. Przykładowe dane:
  5. Problemy w tej strukturze:
  6. Pierwsza postać normalna (1NF)
  7. Kroki do osiągnięcia 1NF:
  8. Nowe struktury po transformacji do 1NF:
  9. Druga postać normalna (2NF)
  10. Wniosek:
  11. Przykład hipotetyczny łamania 2NF:
  12. Problem:
  13. Trzecia postać normalna (3NF)
  14. Problem (zależność przechodnia):
  15. Kroki do osiągnięcia 3NF:
  16. Finalna, znormalizowana struktura (3NF):
  17. Podsumowanie i schemat końcowy
  18. Korzyści z normalizacji:

Proces normalizacji bazy danych: krok po kroku

Normalizacja to proces organizowania kolumn i tabel w relacyjnej bazie danych w celu zminimalizowania redundancji (powtarzania się) danych. Jej głównym celem jest podział dużych, problematycznych tabel na mniejsze, dobrze ustrukturyzowane tabele oraz zdefiniowanie relacji między nimi. Prześledźmy ten proces na przykładzie naszej tabeli `czytelnicy` z biblioteki.

Uwaga: w tym artykule opisano tylko optymalizacje do: 1, 2 i 3 postaci normalnej.

Stan wyjściowy: tabela nieznormalizowana

Zaczynamy od tabeli `czytelnicy_archiwum` (oryginalna tabela z zadania 6), która celowo została źle zaprojektowana.

Struktura tabeli `czytelnicy_archiwum`


CREATE TABLE czytelnicy_archiwum (
  id_czytelnika INT PRIMARY KEY,
  imie_nazwisko VARCHAR(255),
  adres_zamieszkania VARCHAR(255),
  telefony VARCHAR(100)
);
  

Przykładowe dane:

id_czytelnika imie_nazwisko adres_zamieszkania telefony
1 Anna Kowalska ul. Kwiatowa 1, 00-001 Warszawa 123-456-789; 987-654-321
2 Jan Nowak ul. Leśna 2, 30-002 Kraków 555-666-777

Problemy w tej strukturze:

  • Grupy powtarzalne: Kolumna `telefony` przechowuje listę wartości w jednym polu. To łamie podstawową zasadę atomowości.
  • Brak atomowości: Kolumny `imie_nazwisko` i `adres_zamieszkania` przechowują wiele informacji (imię i nazwisko; ulica, kod, miasto). Uniemożliwia to np. sortowanie po nazwisku czy wyszukiwanie po mieście.
  • Anomalie aktualizacji: Zmiana nazwy miasta w adresie wymaga przeszukania i modyfikacji ciągu znaków, co jest niewydajne i podatne na błędy.

Pierwsza postać normalna (1NF)

Zasada: Tabela jest w 1NF, jeśli wszystkie jej atrybuty są atomowe (niepodzielne), a każda komórka zawiera tylko jedną wartość. Nie ma grup powtarzalnych.

Kroki do osiągnięcia 1NF:

  1. Rozbijamy kolumnę `imie_nazwisko` na `imie` i `nazwisko`.
  2. Rozbijamy kolumnę `adres_zamieszkania` na `ulica`, `kod_pocztowy` i `miasto`.
  3. Eliminujemy grupę powtarzalną w kolumnie `telefony`. Tworzymy nową tabelę `telefony`, która będzie przechowywać każdy numer w osobnym wierszu, powiązanym z czytelnikiem przez jego ID.

Nowe struktury po transformacji do 1NF:

  Tabela: czytelnicy_1nf
+--------------+---------------+-------------+------------------+
| id_czytelnika| imie          | nazwisko    | email            | ...
+--------------+---------------+-------------+------------------+
| 1            | Anna          | Kowalska    | a.k@example.com  |
| 2            | Jan           | Nowak       | j.n@example.com  |
+--------------+---------------+-------------+------------------+

  Tabela: adresy
+-----------+---------------+---------+--------------+--------+
| id_adresu | id_czytelnika | ulica   | kod_pocztowy | miasto |
+-----------+---------------+---------+--------------+--------+
| 1         | 1             |Kwiatowa 1| 00-001       |Warszawa|
| 2         | 2             |Leśna 2  | 30-002       |Kraków  |
+-----------+---------------+---------+--------------+--------+

  Tabela: telefony
+-------------+---------------+---------------+
| id_telefonu | id_czytelnika | numer         |
+-------------+---------------+---------------+
| 1           | 1             | 123-456-789   |
| 2           | 1             | 987-654-321   |
| 3           | 2             | 555-666-777   |
+-------------+---------------+---------------+

Teraz każda komórka przechowuje jedną, atomową wartość. Dane są znacznie łatwiejsze do przeszukiwania i zarządzania. Nasza baza jest w Pierwszej Postaci Normalnej.

Druga postać normalna (2NF)

Zasada: Tabela jest w 2NF, jeśli jest w 1NF i każdy atrybut niebędący kluczem jest w pełni funkcyjnie zależny od całego klucza głównego. Ta zasada ma znaczenie tylko wtedy, gdy mamy klucz główny złożony z wielu kolumn.

W naszym przypadku, wszystkie tabele (`czytelnicy_1nf`, `adresy`, `telefony`) mają proste klucze główne (składające się z jednej kolumny: `id_czytelnika`, `id_adresu`, `id_telefonu`). W takiej sytuacji, jeśli tabela jest w 1NF, automatycznie spełnia również warunki 2NF, ponieważ nie ma częściowych zależności od klucza.

Wniosek:

Nasze tabele po osiągnięciu 1NF są już w 2NF, ponieważ nie posiadają kluczy złożonych.

Przykład hipotetyczny łamania 2NF:

Wyobraźmy sobie tabelę `wypozyczenia_z_autorem`, gdzie kluczem głównym jest (`id_czytelnika`, `id_ksiazki`):

  Tabela: wypozyczenia_z_autorem (ŹLE ZAPROJEKTOWANA)
+---------------+------------+---------------------+-------------------+
| id_czytelnika | id_ksiazki | data_wypozyczenia   | autor_ksiazki     |  <-- Klucz główny: (id_czytelnika, id_ksiazki)
+---------------+------------+---------------------+-------------------+
| 1             | 10         | 2023-01-15          | Andrzej Sapkowski |
| 1             | 12         | 2023-02-20          | Stanisław Lem     |
| 2             | 10         | 2023-03-10          | Andrzej Sapkowski |
+---------------+------------+---------------------+-------------------+

Problem:

Atrybut `autor_ksiazki` zależy tylko od części klucza głównego – od `id_ksiazki`. Nie zależy od `id_czytelnika`. To jest częściowa zależność. Jeśli usuniemy ostatnie wypożyczenie książki Sapkowskiego, stracimy informację, kto jest jej autorem. Aby to naprawić, `autor_ksiazki` powinien znajdować się w tabeli `ksiazki`, a nie tutaj.

Trzecia postać normalna (3NF)

Zasada: Tabela jest w 3NF, jeśli jest w 2NF i nie istnieją w niej zależności przechodnie. Oznacza to, że żaden atrybut niebędący kluczem nie może zależeć od innego atrybutu niebędącego kluczem.

Spójrzmy na naszą tabelę `adresy`. Czy jest w 3NF?

  Tabela: adresy
+-----------+---------------+---------+--------------+--------+
| id_adresu | id_czytelnika | ulica   | kod_pocztowy | miasto |
+-----------+---------------+---------+--------------+--------+

W tej strukturze `ulica`, `kod_pocztowy` i `miasto` zależą bezpośrednio od `id_adresu` (klucza głównego). Jednak można argumentować, że `miasto` zależy od `kodu_pocztowego`. To jest zależność przechodnia: `id_adresu` -> `kod_pocztowy` -> `miasto`.

Problem (zależność przechodnia):

Jeśli wielu czytelników mieszka w Warszawie, nazwa „Warszawa” będzie powtórzona w wielu wierszach. Jeśli zrobimy literówkę („Warsawa”), powstanie niespójność. Zmiana nazwy miasta wymagałaby aktualizacji wielu rekordów.

Kroki do osiągnięcia 3NF:

  1. Wydzielamy zależność przechodnią do nowej tabeli. Tworzymy tabelę `miasta` z kolumnami `kod_pocztowy` (jako klucz główny) i `nazwa_miasta`.
  2. W tabeli `adresy` usuwamy kolumnę `miasto` i zostawiamy tylko `kod_pocztowy`, który będzie teraz kluczem obcym wskazującym na tabelę `miasta`.

Finalna, znormalizowana struktura (3NF):

  Tabela: czytelnicy (ostateczna)
+--------------+--------+----------+-----------------+
| id_czytelnika| imie   | nazwisko | ...             |
+--------------+--------+----------+-----------------+

  Tabela: adresy (ostateczna)
+-----------+---------------+----------+--------------+
| id_adresu | id_czytelnika | ulica    | kod_pocztowy | --> (Klucz obcy)
+-----------+---------------+----------+--------------+
                                             |
  Tabela: miasta (nowa)                        |
+--------------+---------------+ <------------'
| kod_pocztowy | nazwa_miasta  |
+--------------+---------------+
| 00-001       | Warszawa      |
| 30-002       | Kraków        |
+--------------+---------------+

  Tabela: telefony (ostateczna, bez zmian)
+-------------+---------------+-------------+
| id_telefonu | id_czytelnika | numer       |
+-------------+---------------+-------------+

Podsumowanie i schemat końcowy

Po przejściu przez wszystkie trzy postacie normalne, nasza początkowo jedna, duża tabela została przekształcona w zestaw mniejszych, połączonych relacjami tabel. Każda tabela opisuje teraz jeden, konkretny aspekt (osoby, adresy, telefony, miasta).

+----------------+      +----------------+      +----------------+
|    CZYTELNICY  |      |     ADRESY     |      |     MIASTA     |
+----------------+      +----------------+      +----------------+
| PK id_czytelnika|<--1--| PK id_adresu   |      | PK kod_pocztowy|
|    imie        |      | FK id_czytelnika|--N-->|    nazwa_miasta|
|    nazwisko    |      |    ulica       |      +----------------+
+----------------+      | FK kod_pocztowy|
       ^                +----------------+
       |
      1|
       |
      N|
+----------------+
|    TELEFONY    |
+----------------+
| PK id_telefonu |
| FK id_czytelnika|
|    numer       |
+----------------+

Korzyści z normalizacji:

  • Redukcja redundancji: Nazwa miasta „Warszawa” jest zapisana tylko raz.
  • Integralność danych: Klucze obce zapewniają, że nie można dodać adresu dla nieistniejącego czytelnika.
  • Brak anomalii: Zmiana nazwy miasta wymaga modyfikacji tylko jednego rekordu w tabeli `miasta`.
  • Elastyczność: Łatwo możemy dodać czytelnikowi drugi adres lub trzeci numer telefonu, po prostu dodając nowy wiersz w odpowiedniej tabeli.
  • Wydajność zapytań: Mniejsze tabele są generalnie szybsze do przeszukiwania i indeksowania.

Nawigacja

← Bazy danych – Model relacji (inne podejście)
Bazy danych – Ewolucja systemów zarządzania danymi →
  • Szukaj

  • Kategorie

    • IT ogólnie (110)
      • Bezpieczeństwo (19)
        • Model AAA (7)
        • Szyfrowanie (1)
      • CCTV (3)
      • Hardware (2)
      • Sieci (25)
        • Cisco (4)
          • Obsługa haseł (2)
        • MikroTik (8)
        • Pomiary w sieciach LAN (6)
          • iptraf-ng (3)
        • Protokół ARP (3)
        • Symulator sieci GNS3 (2)
      • Software (53)
        • Bazy danych (12)
        • Programowanie (3)
        • Systemy operacyjne (15)
          • Linux Debian (14)
        • Windows (7)
      • WiFi (2)
      • Wirtualizacja (26)
    • Różne (1)
  • Ostatnie wpisy

    • Małe wprowadzenie do baz danych
    • Bazy danych – Model relacyjny
    • Bazy danych – Elementy modelowania
    • Bazy danych – Ewolucja systemów zarządzania danymi
    • Bazy danych – Wstęp do normalizacji
  • Strona odwiedzona

    od 11.01.2013

  • Doskonała platforma e-learningowa Uzyskaj certyfikat IT

Proudly powered by WordPress Theme: Parament by Automattic.
7ads6x98y