{{:bazy_danych:normalizacja.pdf|:bazy_danych:normalizacja.pdf}}

====== Normalizacja ======
**Normalizacja** to proces pozwalający na:
  * usunięcie redundancji danych
  * efektywną organizacje danych
  * zmniejszenie anomalii podczas operacji na danych
  * zwiększenie [[integralnosc_danych|integralności]]

Formalna klasyfikacja określająca w jakim stopniu relacyjna baza danych jest znormalizowana nosi nazwę **postaci normalnych**.

Nieznormalizowana baza danych jest podatna na anomalie, ponieważ przechowuje dane w sposób nadmiarowy. Jeżeli jakaś informacja jest przechowywana w dwóch miejscach, ale modyfikowana tylko w jednym następuje zaburzenie integralności danych – zjawisko to znane jest jako anomalia modyfikacji. Znormalizowana baza danych przechowuje dane nie będące [[klucz główny|kluczami głównymi]] tylko w jednym miejscu.

Znormalizowana baza danych jest zaprojektowana w sposób odzwierciedlający prawdziwe zależności pomiędzy danymi w niej przechowywanymi. Pozwala ona na wykonywanie szybkich modyfikacji danych przy minimalnym zagrożeniu naruszenia więzów integralności. Zamiast umieszczania wszystkich danych w jednej tabeli są one rozproszone w wielu, logicznie połączonych tabelach.

====== Postacie normalne ======

Edgar Frank Codd początkowo zdefiniował 3 postacie normalne:
  * 1 NF
  * 2 NF
  * 3 NF

Ogólnie mówiąc 1NF wymusza to, że każdy atrybut może przechowywać jedną wartość, a 2NF i 3NF określają relacje pomiędzy kolumnami nie będącymi kluczami a kluczem głównym.
W praktyce większość baz danych będących w 3NF uznaje się za w pełni znormalizowane. Ostatnie badania wykazują jednak, iż w bazach spełniających 3NF możliwe są wystąpienia anomalii modyfikacji. Postać normalna Boyca-Codda (BCNF) jest nieco bardziej wyrafinowana.
Wprowadzone później postacie 4NF i 5NF dotyczą zależności pomiędzy wielowartościowymi kluczami głównymi. Wprowadzona ostatnio (2005) 6NF dotyczy tylko tabeli tymczasowych.

====== „Nie pierwsza” postać normalna (NF^2 ) ======

Schemat bazy danych niezgodny z żadną postacią normalną pozwala na atrybuty będące zbiorami wartości.

^Osoba^Ulubione kolory^
|Bob|niebieski, czerwony|
|Jane|zielony, żółty, czerwony|

====== Pierwsza postać normalna 1NF ======

**Atrybut może być wyłącznie wartością niepodzielną.**

Tabele nie będące w 1NF:

^Osoba ^Ulubione jedzenie^
|Bob |frytki, pizza, kiełbasa|

^Osoba ^Ulubione jedzenie 1 ^Ulubione jedzenie 2 ^Ulubione jedzenie 3^
|Bob |frytki |pizza |kiełbasa|

Tabela w 1NF:
^Osoba ^Ulubione jedzenie ^
|Bob |frytki|
|Bob |pizza|
|Bob |kiełbasa|

====== Druga postać normalna 2NF ======

**Schemat relacji R jest w 2NF jeśli jest w 1NF i każdy atrybut nie będący kluczem głównym jest funkcjonalnie zależny od klucza głównego.
Dla tabel posiadających pojedyncze klucze główne (złożone z jednej kolumny) 2NF jest zawsze spełniona (przy założeniu, że spełniona jest 1NF).**

Tabela nie będąca w 2NF:
^ID części (PK) ^ID dostawcy (PK) ^Nazwa dostawcy ^Cena ^Adres dostawcy^
|65|2|Stylized Parts|$59.99|VA|
|73|2|Stylized Parts|$20.00|VA|
|65|1|ACME|$49.99|CA|

Tabela jest w 1NF ponieważ atrybuty są wartościami atomowymi (aczkolwiek znak $ w cenie nie powinien występować). 
Zależność pomiędzy ceną a kluczem głównym jest prawidłowa, ponieważ każdy z dostawców może ustalić własna cenę danej części.
Jednak adres i nazwa dostawcy są zależne tylko od ID dostawcy, a nie od całego klucza głównego co nie jest zgodne z definicją 2NF.
Aby schemat bazy był zgodny z 2NF z powyższej tabeli muszą zostać usunięte kolumny Nazwa dostawcy i Adres dostawcy, a przechowywane w nich dane przeniesione do nowej tabeli:
^ID dostawcy (PK)^Nazwa dostawcy^Adres dostawcy^
|1|ACME|CA|
|2|Stylized Parts|VA|

====== Trzecia postać normalna 3NF ======

**Schemat relacji R jest w 3NF jeżeli jest w 2NF i pomiędzy atrybutami nie należącymi do klucza głównego nie występują zależności funkcjonalne.** 
Z powyższego stwierdzenia wynika, że jeżeli tabela składa się z atrybutów, które wszystkie są kluczami to jest ona zgodna co najmniej z 3NF.
Poniżej schemat tabeli będącej w 2NF, ale nie w 3NF.

''NUMER_CZĘŚCI (PRIMARY KEY)\\
NAZWA_PRODUCENTA\\
ADRES_PRODUCENTA''

W tym przypadku adres producenta nie należy do opisu części a samego producenta. Powinien on być zatem przeniesiony do oddzielnej tabeli (adres producenta zależy od jego nazwy, a nazwa producenta nie jest kluczem głównym).
Schemat zgodny z 3NF powinien wyglądać tak:

''NUMER_CZĘŚI (PRIMARY KEY)\\
NAZWA_PRODUCENTA (FOREIGN KEY)''

''NAZWA_PRODUCENTA (PRIMARY KEY)\\
ADRES_PRODUCENTA''

Problem z tabelami nie spełniającymi 3NF polega na tym iż przechowują one nadmiarową ilość danych (adres producenta dla każdej części, a nie dla każdego producenta).

====== Postać normalna Boyce'a-Codda ======

**Postać normalna Boyce'a-Codda wymaga by nie było nietrywialnych zależności funkcjonalnym pomiędzy atrybutami, a czymkolwiek innym niż [[klucz kandydujący]]. Na tym etapie wszystkie atrybuty są zależne od klucza, całego klucza i tylko klucza (wyłączają zależności trywialne takie jak A->A).** 

Łatwa do zapamiętania formuła: //Klucz, cały klucz i tylko klucz – tak mi dopomóż Codd.//

Przykład relacji będącej w 3NF, a nie będącej w BCNF:
Relacja {A,B,C,D}. AB jest kluczem kandydującym, BC jest kluczem kandydującym i A->C.

====== Czwarta postać normalna 4NF ======

**Czwarta postać normalna wymaga by nie było nietrywialnych wielowartościowych zależności pomiędzy zbiorami atrybutów innymi niż te należące do klucza kandydującego.**

Schemat niezgodny z 4NF:

''ID_PRACOWNIKA\\
ID_KWALIFIKACJI\\
ID_KURSU_SZKOLENIOWEGO''

Problem polega na tym iż wprowadzenie kilku kursów może wymagać wpisania kilkukrotnie tego samego ID kwalifikacji (lub pozostawienia go pustego). Prowadzi to do przechowywania nadmiarowej ilości danych.
Ponieważ w rzeczywistości istnieją dwie zależności ''ID_PRACOWNIKA->ID_KWALIFIKACJI'' oraz ''ID_PRACOWNIKA->ID_KURSU_SZKOLENIOWEGO'' powinny zostać stworzone dwie tabele:

''PRACOWNIK_KWALIFIKACJE:\\
ID_PRACOWNIKA\\
ID_KWALIFIKACJI''

''PRACOWNIK_KURS_SZKOLENIOWY:\\
ID_PRACOWNIKA\\
ID_KURSU_SZKOLENIOWEGO''


Osiągnięcie 4NF jest zawsze możliwe, ale nie zawsze pożądane.

====== Piąta postać normalna 5NF ======

**Piąta postać normalna zakłada, że nie istnieją nietrywialne zależności oprócz tych określane przez klucze. Tabela jest w 5NF wtedy i tylko wtedy jeżeli jest w 4NF i każda zawarta w niej zależność jest określona przez klucz kandydujący.**

Tabela niezgodna z 5NF:
^Muzyk^Instrument^Rodzaj^
|James|Pianino|Klasyczna|
|James|Trąbka|Klasyczna|
|Kate|Bębny|Jazz|
|Kate|Pianino|Jazz|
|Kate|Trąbka|Jazz|
|Kate|Klarnet|Jazz|
|Lois|Saksofon|Jazz|
|Lois|Pianino|Klasyczna|
|Lois|Skrzypce|Klasyczna|
|Lois|Gitara|Rock|

Powyżej znajduje się lista muzyków wraz z instrumentami na których grają dany rodzaj muzyki. Możemy założyć, że muzyk gra pewien rodzaj muzyki tylko gdy spełnione są trzy warunki:
  * Muzyk gra na danym instrumencie
  * Muzyk gra dany rodzaj muzyki
  * Instrument należy do danego rodzaju (można na nim grać pewien rodzaj muzyki)

Zgodnie z powyższymi założeniami możliwy jest podział tabeli na trzy tabele:

^Muzyk ^Instrument ^
|James |Pianino|
|James |Trąbka|
|Kate |Bębny|
|Kate |Pianino|
|Kate |Trąbka|
|Kate |Klarnet|
|Lois |Saksofon|
|Lois |Pianino|
|Lois |Skrzypce|
|Lois |Gitara|


^Muzyk ^Rodzaj^
|James |Klasyczna|
|Kate |Jazz|
|Lois |Jazz|
|Lois |Klasyczna|
|Lois |Rock|


^Instrument ^Rodzaj^
|Pianino |Klasyczna|
|Trąbka|Klasyczna|
|Bębny|Jazz|
|Pianino|Jazz|
|Trąbka|Jazz|
|Klarnet|Jazz|
|Saksofon|Jazz|
|Skrzypce|Klasyczna|
|Gitara|Rock|

Połączenie tych tabel da tabelę pierwszą.

====== Postać normalna Domena/Klucz DKNF ======

**Postać Domena/Klucz wymaga by każdy klucz w sposób jednoznaczny identyfikował każdy rząd w tabeli. Domena jest zbiorem dopuszczalnych wartości atrybutu.**

Wymuszając DKNF zapewnia się, iż w bazie nie wystąpią anomalia modyfikacji.

====== Szósta postać normalna 6NF ======

Postać zaproponowana w 2005 dotyczy wyłącznie tabel tymczasowych. Nigdzie nie znalazłem dobrego opisu 6NF więc nie będę tu nic przytaczał.

====== Linki zewnętrzne ======
  * [[http://en.wikipedia.org/wiki/Database_normalization|Oryginalny dokument, który przetłumaczyłem i skróciłem]]
  * [[http://pszwed.ia.agh.edu.pl/labsp98/BazyD/plik1.htm|Kilka definicji (klucze kandydujące i obce, definiacja relacji itd.)]]
  * [[http://www.bkent.net/Doc/simple5.htm | Bardzo dobre objaśnienie 1-5NF (ang.) ]]