Třetí normální forma
Author
Albert FloresTř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. +more # 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ě. +more 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
[url=http://interval.cz/clanky/databaze-a-jazyk-sql/]Databáze a jazyk SQL[/url] - popis prvních čtyř normálních forem (česky)