Jak na návrh databáze, která zvládne i náročnou aplikaci

Ondřej Musil
Jak na návrh databáze, která zvládne i náročnou aplikaci

Databáze je u většiny aplikací to první, co vznikne – a často i to, co se nejmíň řeší. Přitom na ní všechno stojí. To, že databáze „nějak funguje“, ještě neznamená, že je navržená dobře. Skutečná prověrka přichází až ve chvíli, kdy systém začne růst a data počet záznamů v databázi roste do miliónů.

V tomhle článku se podíváme na to, co dělá databázový návrh kvalitním – z pohledu dlouhodobé udržitelnosti, výkonu i čitelnosti. Ukážeme si, proč se relační databáze a SQL stále drží na špici. Projdeme principy normalizace a vysvětlíme si, kdy dává smysl udělat výjimku. 

Jak poznat dobrý návrh databáze?

Návrh databáze se řídí několika klíčovými principy. Prvním je, že duplicitní (redundantní) data jsou problém – zabírají zbytečně místo a zvyšují riziko nekonzistence. Pokud se například e-mail uživatele ukládá na více místech, dříve nebo později dojde k situaci, kdy se jednotlivé verze liší.

Druhým principem je, že správnost a úplnost dat jsou naprosto zásadní. Aplikace, která pracuje s nepřesnými daty, bude vracet chybná čísla, nefunkční logiku a její chování bude nepředvídatelné. Každé rozhodnutí nebo výstup založený na nekonzistentních datech může vést k chybám, které se těžko dohledávají.

  • eliminuje zbytečnou redundanci, která by mohla vést k nekonzistenci a chybám,
  • respektuje vztahy mezi entitami (např. uživatel ↔ objednávka) a zpřístupňuje data bez zbytečných komplikací,
  • zajišťuje integritu dat pomocí klíčů, omezení a pravidel, místo spoléhání na aplikační logiku,
  • počítá s tím, že aplikace poroste – přibudou nové funkce, více dat, nové požadavky.

Relační nebo nerelační?

Rozhodnutí mezi SQL a NoSQL databází není o trendech (i když dřív bylo NoSQL velmi populární a můžeme mluvit o trendu), ale o konkrétním použití.

Relační databáze (např. PostgreSQL, MySQL) jsou ideální, pokud potřebujete:

  • silná integrita dat (např. účetnictví, e-shopy, ERP),
  • komplexní vazby (uživatelé, oprávnění, historie změn),
  • auditovatelnost, transakcekonzistenci.

Nerelační databáze (např. MongoDB, Redis, DynamoDB) jsou naopak flexibilnější. Dávají smysl tam, kde:

  • nestrukturovaná nebo často měnící se data,
  • velké objemy jednoduchých záznamů (logy, telemetry),
  • systémy, kde je prioritou rychlost čtení/zápisu a horizontální škálování.

V praxi často funguje hybridní model – klíčová data běží na SQL, doplňková část (např. cache, realtime logy) na NoSQL.

Proč má normalizace smysl

Cílem normalizace je navrhnout databázi tak, aby:

  • neobsahovala redundantní data,
  • byla konzistentní,
  • umožňovala snadné změny bez vedlejších efektů.

Normalizace probíhá ve více krocích – tzv. normálních formách. Nejčastěji se v praxi používá 1NF až 3NF.

První normální forma (1NF)

Základní požadavek: každý sloupec obsahuje jen jednu hodnotu a každý řádek je jednoznačně identifikovatelný (např. pomocí primárního klíče).

Příklad porušení:

products: id, name, tags (hodnota: „černý, ekologický, letní“)

Řešení:

  • Vytvořit samostatnou tabulku tags
  • Použít spojovací tabulku product_tag

Druhá normální forma (2NF)

Žádný neklíčový sloupec nesmí záviset jen na části složeného klíče (u tabulek s vícesloupcovým primárním klíčem).

Pro většinu moderních databází (s ID jako primárním klíčem) je tento bod často automaticky splněn.

Třetí normální forma (3NF)

Žádný neklíčový sloupec nesmí záviset na jiném neklíčovém sloupci.

Příklad porušení:

orders: id, customer_id, customer_email

Zde e-mail zákazníka závisí na customer_id, ne přímo na objednávce. Správně by měl být jen v tabulce customers.

Přínosy normalizace:

  • Úspora místa v databázi
  • Jednodušší aktualizace (změna e‑mailu na jednom místě)
  • Přehlednější a logičtější struktura

Pokud si by vás zajímalo více detailů ohledně normalizace, doporučuji tento jednoduchý přehled. Database Normalization Explained – Essential SQL

Kdy má smysl denormalizovat

Občas se hodí pravidla porušit – vědomě. 😉

Denormalizace znamená ukládat některá data duplicitně, aby se zrychlilo čtení nebo zjednodušily dotazy (např. reporty).

Příklad:

  • Do tabulky orders můžete přidat customer_email, pokud ho často potřebujeme při exportu.
  • Do products můžete přidat category_name, pokud často filtrujeme podle názvu kategorie.

Je ale důležité mít jasno:

  • Denormalizace je vědomý kompromis.
  • Vyžaduje dodatečnou logiku, která zajistí, že se data synchronizují.
  • Hodí se hlavně tam, kde je čtení výrazně častější než zápis.

Nejčastější chyby při návrhu databáze

  • Absence normalizace – Duplicitní data, nejednoznačnosti, zbytečně velké tabulky.
  • Přílišná (nebo žádná) denormalizace – Příliš složité JOINy vs. zbytečné kopírování dat. Je potřeba najít rovnováhu podle konkrétního use-casu.
  • Špatně zvolené datové typy – Např. použití TEXT místo VARCHAR, INT tam, kde stačí TINYINT
  • Chybějící (nebo špatně nastavené) primární a cizí klíče
  • Nekonzistentní pojmenování tabulek a sloupců – Např. user_id vs. userid vs. id_user
  • Návrh bez ohledu na výkon – Např. nedomyšlené indexy, n+1 dotazy, pomalé dotazy přes LIKE
  • Zanášení business logiky do databáze – Triggery, stored procedury a složité pohledy často zvyšují složitost
  • Nesprávné navrhování vazeb n:n – Chybí spojovací tabulky nebo mají víc dat, než by měly (např. pivot tabulka obsahuje i logiku, co tam nepatří).
  • Chybějící auditní a stavové sloupce – Není možnost sledovat změny (created_at, updated_at, deleted_at),

Nemá smysl návrh databáze podceňovat

Studie provedené na velkých datasetech (např. IMDb) ukázaly, že dobře normalizovaný návrh:

  • snižuje datovou velikost o 10 – 15 %,
  • zrychluje klíčové dotazy i několikanásobně,
  • má nižší spotřebu paměti a nižší zatížení CPU.

Navíc přináší nižší náklady na údržbu – nové funkce se přidávají rychleji, kód je přehlednější a méně náchylný k chybám.

Jak postupovat při návrhu databáze

  1. Definujte účel databáze a hlavní scénáře použití – Než začnete navrhovat schéma, ujasněte si, k čemu bude databáze sloužit. Jaká data bude ukládat? K čemu bude sloužit (čtení, zápis, filtrování)?
  2. Určete základní entity (objekty systému) – Zaměřte se na klíčové prvky aplikace – například uživatel, objednávka, produkt, článek. Každá z těchto entit se zpravidla stane samostatnou tabulkou.
  3. Navrhněte vztahy mezi entitami – 1:1, 1:N, N:M (pivot), případně dědičnost (např. různé typy uživatelů).
  4. Navrhněte první verzi tabulek – bez ohledu na ORM
  5. Zkontrolujte normalizaci – 1NF, 2NF, 3NF
  6. Zvažte výjimky – denormalizaci, pohledy, výpočetní sloupce
  7. Zvolte vhodné datové typy – Určete přesné typy (VARCHAR, INT, BOOLEAN, DATE, DECIMAL atd.) a nastavte rozumné limity (NOT NULL, UNIQUE, výchozí hodnoty apod.).
  8. Zajistěte datovou integritu pomocí klíčů
  9. Navrhněte strategii pro mazání dat a jejich historii – Rozhodněte, zda budete data mazat „hard-delete“ nebo „soft-delete“. Potřebujete uchovávat historii změn, auditní stopy, verze záznamů?
  10. Identifikujte klíčové dotazy a připravte indexy – Zaměřte se na to, jak budou data nejčastěji čtena – podle toho navrhněte vhodné indexy.

Tip z praxe: Pomocí seederů a factory tříd si vygenerujte statisíce záznamů a simulujte reálné dotazy. Snadno tak odhalíte slabá místa, nevhodné indexy, nebo n+1 problémy co nejdříve.

Závěr

Dobře navržená databáze není ta, která jen aktuálně funguje. Je to ta, která je od začátku připravená na růst – počítá s větším množstvím dat, s rozšiřováním funkcí i s tím, že systém nebude spravovat jeden člověk, ale celý tým.

Není to o zbytečné složitosti, ale o promyšleném základu, který unese i další vývoj. Správné schéma se nemusí měnit při každé nové funkci – protože s ní už od začátku počítá.

A právě taková databáze dává projektu klidný prostor růst bez technického dluhu.

Ondřej Musil
Ondřej Musil

Od roku 2018 vytvářím weby a aplikace na míru ve WordPressu a Laravelu. Miluju funkční systémy, čistý kód a práci, která dává smysl – nejen klientovi, ale i mně samotnému. Baví mě hledat jednoduchá a chytrá řešení, když věci na první pohled vypadají složitě.

Podobné příspěvky

Hledáte spolehlivého vývojaře?

Nemusíme hned začít – stačí se pobavit o tom, co potřebujete. Někdy i krátký rozhovor hodně vyjasní.

Ozvěte se mi