Pavel Snehule:
Co si mysliteo tom, kdyz vyvojari kvuli performance problemum zacnou denormalizovat tabulky v databazi? Ja si myslim, ze to je spatny postup, ze to nefunguje, a ze to akorat zvysi bordel v aplikaci. Podle me u beznych 95% servis v SOA architekture jsou perfromance issue zpusobene bordelem, spatnymi indexy, spatnymi sql dotazy (bordel), blokujicimi transakcemi (kvuli bordelu v kodu), a nema to moc spolecneho s tim, ze tabulkuy jsou normalizovane. A denormalizace jenom prileva olej do ohne vseobecneho bordelu, ktery zpusobuje nejen problemy s performance, ale i bugy.
Potrebuju nejakou munici na vyvojare, az budou pindat ze serivce ma performance issues a budou chtit jako prvni stupidni reseni co je napadne delat denormalizaci.
Na to se nedá jednoduše odpovědět. U OLAPu, když máte star schema nebo snowflake schéma, tak se běžně pracuje s silně denormalizovanými daty (a k tomu se používají databáze optimalizované pro OLAP - sloupcové analytické databáze - vertika, monet nebo snowflake. Tím, že máte předem známé schéma, tak pak můžete používat generické nástroje pro tvorbu MD reportů. OLAP databáze jsou ale sekundární - nejsou primární, a pracuje se tam s transformovanými daty, takže zřejmé nevýhody nenormalizované databáze jsou potlačené.
Pokud máte OLTP databázi s dobře navrženým schématem, tak si myslím, že denormalizace je blbost. Pak mraky dotazů jsou naprosto nesmyslný typu SELECT ... WHERE id = x LIMIT 1. To rozhodně výkonnostně nepomůže. Databáze má evidenci o tom, které hodnoty jsou unikátní, a dokáže tuto informaci využít. Denormalizací redukujete počet unikátních indexů. Nehledě na to, že pak, pokud musíte, tak napsat SQL v ruce bolí, a je neskutečně nečitelné, protože musíte redukovat duplicity - musíte nadužívat DISTINCT, případně zbytečně používat agregace MIN, MAX. To všechno blokuje optimalizaci a má velkou režii. Určitě denormalizací něco zrychlíte, ale dost věcí jinde si zkomplikujete a zpomalíte. Někdy na opravdu velkých tabulkách může mít smysl si přikopírovat sloupec, podle kterého budete filtrovat (někdy se vyplatí data před filtrovat před JOINem, nebo předagregovat). Ale to se bavíme o tabulkách, které mají desítky možná stovky miliónů záznamů.
Pokud se JOIN provádí na úrovni aplikace (díky ORM - kdy v cyklu v aplikaci se volá nějaká metoda, která stahuje data z db), tak se implementuje ta nejpomalejší metoda JOINu, která existuje - nested loop - navíc zpomalený velkou režií vzdálené komunikace. Stáhnout si z jakékoliv databáze 1M hodnot po jednom řádku je neskutečně pomalé. Tím, že denormalizuji, abych získal lepší výkon s ORM, tak já si myslím, že ten nejhorší způsob, co může být. Bohužel ORMka jsou natolik komplikovaná, že tahle dementní cesta, je jediná, která je dosažitelná pro běžného programátora. SQL neumí, a přetlačit ORM také ne - to není o změně ORM, ale o změně patternů (jak to ORM použít).
Pokud si nešikovně namapujete objekty do relační databáze (snažíte se o implementaci dědičnosti na úrovni databáze), tak se může stát, že ve vašem schématu nebude entitě odpovídat tabulka. Pak někdo dělá denormalizaci - ale to není denormalizace, ale materializace entity. V podstatě se dostáváte do správného stavu.
Pokud máte správně znormalizované schéma (a vaše aplikace je OLTP), tak je denormalizace blbost (defakto se snažíte vytvořit jakési materializované pohledy) pro ORM, ale pak se ta databáze hrozně blbě používá. To máte osypky, když máte napsat SQLko.
Je to podobné jako s typovým systémem. V podstatě si můžete vystačit s varcharem (a také jsem viděl takové databáze), ale ve výsledku je to dost pomalé (neefektivně uložená data, neustálé konverze), všechno si musíte udělat sami, a neupozorní vás to na chyby, na které by vás to upozornit mohlo.