Modelování dat v MongoDB: vnořené dokumenty versus reference
Volba mezi vnořenými dokumenty a referencemi je v MongoDB tím prvním, co musíte vyřešit, ještě než napíšete první dotaz. MongoDB není relační databáze a nutit do ní normalizovaný model znamená přicházet o většinu výhod. Na druhou stranu ani bezhlavé vnořování všeho do jednoho dokumentu nefunguje. Rozhoduje způsob čtení a zápisu, ne teorie.
Vnořené dokumenty se hodí tam, kde data čtete vždy společně a patří k jednomu celku. Typický příklad je objednávka s položkami nebo uživatel s adresou. Jeden dotaz vrátí všechno, žádné JOINy, žádné dodatečné roundtripy. Pokud ale vnořené pole roste bez limitu, narazíte na 16MB limit dokumentu a zápisy začnou být drahé. Zvažte také, jak často se vnořená část mění nezávisle na zbytku. Pokud se mění pořád, vnoření přestává dávat smysl. Obecně platí, že data, která se čtou spolu, mají být spolu. Když se ptáte, kdy použít NoSQL, odpověď často vede právě k tomuto principu agregace.
Reference používejte, když jsou data sdílená mezi mnoha dokumenty nebo když rostou neomezeně. Klasický případ je autor a jeho články, kde autor existuje jednou a článků jsou tisíce. Referenci držíte jako ObjectId a při čtení použijete $lookup nebo druhý dotaz. Cena je vyšší latence a složitější aplikační logika, protože MongoDB neumí kaskádové mazání ani transakce přes více dokumentů zdarma. Výhodou je konzistence na jednom místě a možnost měnit referencovaný dokument bez přepisování všech ostatních.
V praxi se nejvíc osvědčuje hybridní přístup. Vnořte to, co potřebujete zobrazit okamžitě, a zbytek odkažte referencí. Duplikujte jen ta pole, která se nemění nebo jejichž drobná nekonzistence nevadí. Model navrhněte podle dotazů, které skutečně poběží, a ne podle toho, jak by vypadal v ER diagramu. Až budete váhat, napište si konkrétní scénáře čtení a zápisu a spočítejte, kolik dotazů každá varianta vyžaduje. Vyhraje ta s menším počtem a předvídatelnějším výkonem.