Takédatabase normalization, normální formyPokročilý
Definice
Normalizace databáze je způsob návrhu relační databáze, při kterém se data rozdělují do tabulek podle významu a závislostí, aby se omezila duplicita a nekonzistence. Typicky se opírá o normální formy, primární klíče a cizí klíče; výsledkem je čistší model, ale někdy složitější dotazy.
Proč normalizace rozděluje tabulky
Normalizace databáze řeší situace, kdy jedna tabulka míchá více různých věcí: zákazníka, objednávku, položku, adresu nebo stav platby. Opakovaný údaj pak není jen plýtvání místem. Důležitější je riziko, že stejná informace začne žít v několika verzích. Změna e-mailu v jedné objednávce, ale ne v dalších, vytvoří nekonzistenci, kterou aplikace později těžko opravuje.
Normalizovaný model ukládá jednu skutečnost na jedno zodpovědné místo. Tabulka customers drží zákazníky, tabulka orders objednávky a vztah mezi nimi vyjadřuje cizí klíč. Relační databáze tím získá pravidla, podle kterých může odmítnout neplatný zápis, například objednávku od neexistujícího zákazníka.
Normální formy jako kontrolní seznam
Normální formy nejsou kouzelný algoritmus, který automaticky vytvoří správné schéma. Normální formy jsou sada otázek nad funkčními závislostmi: na čem hodnota závisí a kde má být uložená. První normální forma typicky vyžaduje, aby buňka neobsahovala seznam hodnot místo jedné hodnoty. Druhá normální forma řeší závislost na celém složeném klíči. Třetí normální forma odstraňuje nepřímé závislosti mezi neklíčovými sloupci.
Praktický návrh často nekončí u mechanického splnění definic. Databázový modelář musí znát význam dat v doméně. Sloupec country_name může být jen text na faktuře, nebo odkaz na číselník zemí s daňovými pravidly. Stejný tvar tabulky tedy může být v jednom systému přijatelný a v jiném nebezpečný.
Co normalizace stojí při čtení
Normalizace databáze obvykle zjednodušuje zápisy a změny, ale čtení může vyžadovat více spojení tabulek. Detail objednávky se skládá ze zákazníka, položek, cen, doručovací adresy a platebního stavu. Dotaz proto často používá JOIN. Správně navržený index pomůže databázi najít související řádky bez plného procházení tabulek, ale index sám nevyřeší špatně pochopené vztahy.
Nadměrné rozsekání modelu může být stejně problematické jako jedna obří tabulka. Tabulka s kódem a názvem dává smysl pro stabilní číselník, ale samostatná tabulka pro každý drobný příznak může zhoršit čitelnost schématu i dotazů. Dobrá normalizace hledá hranici, kde data mají jasné vlastnictví a aplikace zůstává udržovatelná.
Kdy dává denormalizace smysl
Denormalizace je vědomé porušení čistého modelu kvůli konkrétnímu cíli, nejčastěji rychlejšímu čtení nebo jednodušším reportům. Analytická tabulka může obsahovat název produktu i kategorii přímo u prodeje, protože historický report potřebuje rychle číst velké objemy dat. Takové rozhodnutí má být zdokumentované a chráněné pravidly, která udrží kopie údajů synchronní.
Normalizace databáze tedy není náboženství, ale technika návrhu. V transakční aplikaci, kde se data často mění a konzistence je zásadní, bývá silně normalizovaný model bezpečnou výchozí volbou. V datovém skladu, vyhledávání nebo cache vrstvě může být výhodnější uložit odvozený pohled, který se pravidelně obnovuje z autoritativních tabulek.
Příklady z praxe
Zákazník opakovaný v objednávkách
E-shop ukládal e-mail a jméno zákazníka přímo do každé objednávky. Po změně e-mailu zůstaly starší objednávky s původní hodnotou a zákaznická podpora hledala zákazníka pod dvěma identitami. Rozdělení na tabulky zákazníků a objednávek přesunulo kontakt na jedno místo a objednávky na něj jen odkazují.
-- Problematický tvar: zákazník se opakuje u každé objednávky CREATE TABLE orders_flat ( order_id integer PRIMARY KEY, customer_email text, customer_name text, ordered_at timestamp ); -- Normalizovaný tvar: zákazník má vlastní tabulku CREATE TABLE customers ( customer_id integer PRIMARY KEY, email text UNIQUE NOT NULL, name text NOT NULL ); CREATE TABLE orders ( order_id integer PRIMARY KEY, customer_id integer NOT NULL REFERENCES customers(customer_id), ordered_at timestamp NOT NULL );Seznam štítků v jedné buňce
Katalog produktů měl ve sloupci `tags` hodnoty jako `notebook,akce,skladem`. Filtr podle štítku byl pomalý a překlepy vytvářely duplicitní varianty stejného štítku. Spojovací tabulka `product_tags` umožnila ukládat každý vztah produkt-štítek samostatně a databáze začala hlídat duplicity přes primární klíč.
CREATE TABLE products ( product_id integer PRIMARY KEY, name text NOT NULL ); CREATE TABLE tags ( tag_id integer PRIMARY KEY, label text UNIQUE NOT NULL ); CREATE TABLE product_tags ( product_id integer REFERENCES products(product_id), tag_id integer REFERENCES tags(tag_id), PRIMARY KEY (product_id, tag_id) );
Časté omyly
- MýtusNormalizace databáze znamená, že se musí odstranit úplně všechny duplicity.
- Ve skutečnostiNormalizace databáze odstraňuje škodlivé redundance vyplývající ze špatných závislostí. Některé kopie dat mohou být záměrné, například historická cena na faktuře nebo odvozená analytická tabulka.
- MýtusTřetí normální forma je vždy konečný a nejlepší stav návrhu.
- Ve skutečnostiTřetí normální forma je užitečný praktický cíl, ale ne univerzální maximum. Některé modely potřebují přísnější kontrolu závislostí, jiné naopak vědomou denormalizaci kvůli reportům nebo výkonu čtení.
Časté dotazy
- Má smysl normalizovat databázi i v malém projektu?
- Normalizace databáze je obvykle dobrý výchozí bod pro transakční systémy, ale malý projekt nemusí hned modelovat každou věc do nejjemnějšího detailu. Důležité je poznat údaje, které se budou měnit nezávisle a mohou se opakovat. Zákazník, objednávka, produkt a adresa si samostatné tabulky často zaslouží i v jednoduché aplikaci, protože pozdější oprava duplicit bývá dražší než rozumný návrh na začátku.
- Zpomalí normalizace databáze aplikaci?
- Normalizace databáze může zvýšit počet spojení v dotazech, ale sama o sobě neznamená pomalou databázi. Výkon závisí na objemu dat, indexech, dotazech, plánovači databáze a vzorcích používání aplikace. Normalizovaný model často zrychlí zápisy a sníží počet chyb, protože se upravuje méně míst. Pokud jsou čtecí dotazy kritické, běžným řešením je cílený odvozený pohled, materializovaná tabulka nebo cache, ne návrat k náhodným duplicitám.
- Jak poznám, že tabulka porušuje normalizaci databáze?
- Normalizace databáze se pozná podle závislostí mezi hodnotami, ne jen podle počtu tabulek. Podezřelé jsou sloupce s opakovanými skupinami, seznamy hodnot v jedné buňce, údaje zákazníka uložené u každé objednávky nebo atributy, které závisí na jiném neklíčovém atributu. Praktický test zní: když se jedna skutečnost změní, musí se upravit více řádků nebo více tabulek? Pokud ano, model pravděpodobně obsahuje zbytečnou duplicitu.
- Stačí pro normalizaci databáze používat cizí klíče?
- Normalizace databáze chrání logickou konzistenci modelu, zatímco cizí klíče jsou jeden z nástrojů, jak pravidla vynutit v relační databázi. Návrh může být teoreticky normalizovaný, ale bez omezení v databázi zůstává část odpovědnosti na aplikaci. Cizí klíč například zabrání objednávce od neexistujícího zákazníka. Normalizace rozhoduje, kam vztah patří; databázové omezení hlídá, že se vztah skutečně dodržuje.
Zdroje
- Database normalization(otevře se v novém okně)
- 5.5. Constraints(otevře se v novém okně)
- SQLite Foreign Key Support(otevře se v novém okně)
- Description of the database normalization basics(otevře se v novém okně)