Třetí normální forma
Třetí normální forma (3NF) je soubor doporučení (metodika) pro návrh datové struktury databáze, jehož dodržení vede k optimálnímu využití vlastností systému OLTP při tvorbě databázových aplikací. 3NF obsahuje jako svou podmnožinu druhou normální formu (2NF) a první normální formu (1NF):
- Eliminuj duplicitní sloupce v jednotlivých tabulkách.
- Pro každou skupinu dat s jasně vymezeným významem vytvoř zvláštní tabulku, každý řádek opatři unikátním primárním klíčem.
- Obsahem jednotlivých sloupců tabulky by měla být jednoduchá, dále nedělitelná informace.
- Podmnožinu dat se shodnou hodnotou pro určitý sloupec tabulky převeď do samostatné tabulky a spoj s původní tabulkou cizím klíčem.
- Odstraň z tabulky sloupce, které jsou přímo závislé na jiné skupině sloupců tabulky než pouze na primárním klíči.
Tak, jak jsou zde zapsány, působí jednotlivá doporučení velice obecně a (alespoň pro toho, kdo již někdy nějakou databázovou strukturu navrhoval) v podstatě samozřejmě. Pokusme se demonstrovat jejich použití na jednoduchém příkladu:
Příklad
Zadání: Navrhněte datovou strukturu (tabulku nebo skupinu tabulek) pro uložení seznamu oddělení firmy, který bude obsahovat číslo oddělení, adresu budovy, kde oddělení sídlí, jméno, příjmení a plat šéfa a jméno, příjmení a plat všech zaměstnanců oddělení.
První pokus o řešení
Vytvořím si jednu tabulku Oddělení, která bude obsahovat následující sloupce:
- číslo oddělení
- adresa budovy
- jméno, příjmení a plat šéfa
- jméno, příjmení a plat prvního zaměstnance
- jméno, příjmení a plat druhého zaměstnance
- jméno, příjmení a plat třetího zaměstnance
- … a tak dále podle toho, kolik má zaměstnanců největší oddělení ve firmě
Moc hezké, ale zkuste v této struktuře napsat příkaz SELECT, který vybere deset nejlépe placených zaměstnanců. Nebo třeba SELECT, který vybere oddělení s více než deseti zaměstnanci.
Tato struktura rozhodně nesplňuje bod 3 z výše uvedených doporučení – adresa by měla být rozdělena na ulici, město, PSČ a stát a pro každého zaměstnance by mělo být uvedeno zvlášť jméno, zvlášť příjmení a zvlášť plat.
Tato struktura také rozhodně nesplňuje bod 2 – jsou zde dohromady v jedné tabulce smíchány údaje o lidech a o odděleních.
Druhý pokus o řešení
Vytvořím dvě tabulky:
Tabulka Oddělení:
- číslo oddělení (primární klíč)
- adresa budovy – ulice
- adresa budovy – číslo
- adresa budovy – město
- adresa budovy – PSČ
- adresa budovy – stát
- ID šéfa (cizí klíč do tabulky Lidé)
Tabulka Lidé:
- ID člověka (primární klíč – uměle vytvořené zaměstnanecké číslo, žádný z existujících sloupců ani jejich skupinu nemohu použít jako primární klíč, neboť ve firmě mohou existovat dva Josefové Novákové pracující ve stejném oddělení za stejný plat)
- jméno
- příjmení
- plat
- číslo oddělení (cizí klíč do tabulky Oddělení)
Už je to o něco lepší – rozhodně už dokážu pomocí SQL příkazu najít nejlépe placené zaměstnance nebo zjistit počet zaměstnanců jednotlivých oddělení. Problém je ještě v doporučení číslo 4 v případě tabulky Oddělení – firma bude nejspíš mít hodně oddělení, ale málo budov (možná dokonce jenom jednu), rozhodně bude hodně oddělení sedět vždy ve stejné budově. V tabulce Oddělení se mi tedy bude pořád dokola opakovat několik málo adres budov. Správně by tedy měly být adresové sloupce vyvedeny do zvláštní tabulky.
Třetí pokus o řešení
Vytvořím tři tabulky:
Tabulka Oddělení:
- číslo oddělení (primární klíč)
- ID šéfa (cizí klíč do tabulky Lidé)
- ID budovy (cizí klíč do tabulky Budovy)
Tabulka Lidé:
- ID člověka (primární klíč)
- jméno
- příjmení
- plat
- číslo oddělení (cizí klíč do tabulky Oddělení)
Tabulka Budovy:
- ID budovy (primární klíč – uměle vytvořené pořadové číslo budovy)
- adresa budovy – ulice
- adresa budovy – číslo
- adresa budovy – město
- adresa budovy – PSČ
- adresa budovy – stát
To už vypadá docela dobře. Dalo by se diskutovat o tom, jestli číslo oddělení je opravdu vhodný primární klíč, co se stane, když dojde k přečíslování oddělení, nebo třeba o tom, že podle PSČ a státu dokážu určit město, takže podle doporučení 5 je položka adresa budovy – město vlastně přebytečná, ale v zásadě jsme se díky pravidlům 3NF dostali ke struktuře, se kterou by nemělo být složité pracovat pomocí příkazů jazyka SQL.
Externí odkazy
- Databáze a jazyk SQL – popis prvních čtyř normálních forem (česky)