Autor Zpráva
Suta
Profil
Jelikož nemám nikterak velké zkušenosti s návrhem složitější databázové struktury, obracím se s prosbou o radu.

Nastíním logiku aplikace:
Rád bych ukládal strukturu zanořených OBJEKTŮ, kde každý objekt může být uvnitř jiného objektu (či uvnitř jiných objektů), objekty jsou různých typů a na každý objekt mohou být navázány speciální moduly (chování), zde je příklad:

Ukázka tří odlišných OBJEKTŮ:
1. TEXT_NODE (prostý text, ukázka nejjednoduššího objektu)
2. PANEL (panel s konkrétními charakteristikami, např. vysouvací, středně složitý objekt)
3. PHOTO_GALLERY (nejsložitější koncepce s variabilními možnostmi, může obsahovat různé typy objektů, jak typu PANEL, tak typu TEXT_NODE)

Pro co nejsrozumitelnější vysvětlení zůstanu u prvních dvou typů, textový řetězec (TEXT_NODE), který bude uvnitř panelu (PANEL).

Nejzákladnějším řešením, s nímž jsem na začátku pracoval, nicméně není vyhovující, je uložení v html podobě, tedy takto:

"<div class='panel' objectType='panel'><span objectType='textNode'>Textový obsah</span></div>".

Řešení je sice velmi jednoduché, ale při potřebě upravit textový obsah je potřeba složitého parsování textového obsahu. Dále jde o to, že na daném panelu může být aplikováno spousta modulů, např. modul "absolute_moving", který bude značit (jde o příklad), že při uchopení panelu s ním můžu pohybovat ve vymezeném prostoru...

Dostávám se tedy k tomu, že každý objekt by měl být v databázi uložen samostatně (jak textový řetězec, tak panel), a zde je právě několik možností, z nichž nevím, kterou zvolit.

Varianta, o níž přemýšlím:
Rodičovský objekt bude vždy obsahovat odkazy na dceřiné objekty. Tzn. PANEL bude obsahovat seznam id všech vnitřních objektů, jedním z nich bude i onen textový řetězec (TEXT_NODE).

Struktura databáze by pak byla následující:

Poznámka: sloupec children_id by v praxi pochopitelně neobsahoval string čítající seznam id vnitřních objektů, samozřejmě by se jednalo o propojovací tabulku, použil jsem opět pro jednoduchost.

Každý TYP OBJEKTU by pak vyžadoval speciální přidruženou tabulku, kde by byla specifikována samotná data a chování.



Na uvedené logice je snad patrné, čeho chci dosáhnout. Nicméně mám jednu obrovskou obavu. Výše uvedený příklad obsahuje jednoduché zanoření jednoho objektu (textového řetězce) uvnitř jiného objektu (v tomto případě "nějakého" panelu s určitými charakteristikami). Nicméně v případě, že půjdu do složitějších kombinací a vytvořím celou šablonu, v níž bude spousta objektů různých typů, které v sobě mají další děti atd., pak se bojím o efektivitu a odezvu celé aplikace především z důvodu mnoha sql dotazů...

Výše uvedená logika však na druhou stranu dovolí krásně pracovat jak s menšími částmi, tak s větší datovou strukturou. Chci-li načíst určitý panel, pak začnu u něj a získám jej včetně jeho vnitřních textových objektů. Panel zároveň může být součástí fotogalerie, začnu-li načítání u ní, pak získám tuto fotogalerii včetně všech vnitřních panelů, jejich textových obsahů atd...

Prosím kohokoliv zkušeného o postřehy a radu, jelikož udělám-li zásadní chybu v tomto návrhu, přinese mi to v budoucnu obrovské potíže.

Předem díky!
Sir Tom
Profil
Suta:
Na každý typ objektu vytvoř tabulku, a potom vytvoř jednu tabulku např. vztahy, která se jmenuje relations, kde budeš mít položky:
parent_type | parent_id | child_type | child_id
Tato tabulka si bude pamatovat všechny vazby mezi rodičem a potomkem (takže vlastně podle idčka a typu rodiče si najdu jeho potomka v tabulce relations - nikoliv, že by si rodič sám pamatoval potomka).
Suta
Profil
Reaguji na Sir Toma:
- nikoliv, že by si rodič sám pamatoval potomka
Takto bych uvažoval v případě, že by jeden potomek mohl být součástí pouze jednoho rodiče. Já však potřebuji pracovat s objekty, které mohou být součástí několika dalších objektů.

Pro přiblížení: např. panel, který je systémový (nemůže být upravován), ale načíst jej a pracovat s ním může spousta uživatelů. Jinými slovy, vytvořím si vlastní panel, a do něj (mimo jiné) načtu zmíněný panel. To samé může udělat více uživatelů, nebo i já stejný panel můžu načíst vícekrát a uložit do různých "rodičů". V databázi pak bude několik různých "uživatelských" panelů, u nichž jedním z vnitřních obsahů bude onen systémový panel.

Jak tedy v tomto případě?

Jinak otázka týkající se použitelnosti a odezvy aplikace (vzhledem ke "skládání výsledné podoby aplikace" na základě spousty sql dotazů) stále zůstává k okomentování.
Tori
Profil
Suta:
Další možnost je ukládat data do XML.

Co se týká databáze, rozdělila bych tabulky spíš nějak takto:
struktura - stromová struktura, jen informace o tom, že prvek s určitým ID je potomkem jiného ID *
objekty - typy objektů - text, panel, galerie,..
moduly, vlastnosti - typy dostupných modulů
umístění objektů - propojení struktury s objekty, určuje jaký typ objektu je na daném uzlu
vlastnosti objektů - propojení modulů s objekty anebo uzly ve struktuře (podle toho, jestli modul objekt může mít tytéž vlastnosti bez ohledu na umístění, anebo ne)

* viz Storing Hierarchical Data in a Database, part 2 nebo česky Metody ukládání stromových dat v relačních databázích
Suta
Profil
Reaguji na Tori:
Další možnost je ukládat data do XML.
Principy XML znám, nikdy jsem v něm však nepracoval. Jak konkrétně by XML mohlo vyřešit můj požadavek? Zhruba před dvěma měsíci jsem několik hodin nad XML seděl a přemýšlel nad jeho aplikací pro uvedené potřeby, zavrhl jsem jej však s tím, že mi nikdy nemůže poskytnout potřebnou flexibilitu, kterou mi zaručí data uložená v databázových tabulkách. Konkrétně mám na mysli to, že budu-li chtít určitou část (třeba onen systémový panel) načítat na více místech (tedy i UKLÁDAT odkaz na něj v různých rodičích), nevím, jak bych toto řešit pomocí XML.

Navrhované rozdělení databáze je zajímavé, musím si jej pořádně promyslet, nevím, jestli dokážu reagovat dnes...
Tori
Profil
Suta:
budu-li chtít určitou část (třeba onen systémový panel) načítat na více místech (tedy i UKLÁDAT odkaz na něj v různých rodičích), nevím, jak bych toto řešit pomocí XML
Jak to provést bez duplicit, že. Trochu krkolomně by snad šlo tohle, ale nevím, jestli to je dobrý nápad. Osobně bych taky preferovala databázi.
<xml>
  <struktura>
    <prvek typ="panel">
      <prvek typ="text">text text</prvek>
    </prvek>
  </struktura>

  <moduly>
    <panel>
      <vlastnost nazev="nextModule1" />
      <vlastnost nazev="absoluteMoving" />
    </panel>
    <text>
      <vlastnost nazev="editable" />
    </text>
  </moduly>
</xml>
Tori
Profil
Suta:
Čistě ze zvědavosti - jak jste tu DB nakonec navrhl?

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: