ugrás a tartalomhoz

Hierarchikus adatkezelés SQL-lel PHP-ben I.

Poetro · 2004. Dec. 15. (Sze), 02.41
Hierarchikus adatkezelés SQL-lel PHP-ben I.
Adatainkat gyakran hierarchikus struktúrában tároljuk. Gondoljunk például a fájlrendszer esetén a könyvtárszerkezetre, de rengeteg más példát is találhatunk. És hogy szakmánál maradjunk: ilyen a többszintű menük vagy például a fórumok témáinak szerkezete. Ha eddig nem volt ötleted, hogy hogyan tudnál ilyen jellegű adatokat eltárolni, megmutatok pár módszert rávilágítva az egyes buktatókra.

Cikkünk a sitepoint.com Storing Hierarchical Data in a Database cikkje alapján készült.


A sorozatban megjelent

Példaprobléma

Maga a probléma, mint láttuk elég általános, mégse feltétlenül tudunk rá jól használható és hatékony megoldást. Ebben a cikkben megpróbálok bemutatni két megoldást, és közülük a hatékonyabbhoz a konkrét PHP-s megvalósítást is megnézzük egy erre a célra kialakított osztály képében.

Maga a fa struktúra elég egyszerűen néz ki:
  • a fának van egy gyökere
  • a gyökérből ágazhatnak ki ágak, azoknak lehetnek további ágai
  • ha egy ágnak nincsenek további ágai, akkor az ágat levélnek hívjuk
Képzeljünk el egy ideális családfát, és máris érteni fogjuk a fastruktúra értelmét.

A cikkben alkalmazott megközelítéssel először Gijs Van Tulder Storing Hierarchical Data in a Database című cikkében találkoztunk, a sitepoint.com honlapon. A következőkben olvasható kódrészletek a fenti cikkben található példákon alapulnak.


Egy képzeletbeli fórum témaszerkezetén fogom bemutatni a megoldást, melynek váza a következőképpen néz ki:
Programozás  
|-PHP
|  |-Stringkezelés
|  |-PEAR
|     |-Mail
|     |-HttpClient
|
|-HTML        
   |-CSS
   |  |-kiválasztók
   |-XHTML

Elméleti háttér

Az adatok tárolását valamilyen adatbázis kezelőben szeretnénk megvalósítani; legyen ez az egyszerűség kedvéért a MySQL, úgyis nemrég került fel egy hasznos cikk a telepítéséről: MySQL 4.1 telepítése Windows rendszereken.
A megoldásokban kétféleképpen tárolhatjuk az adatokat:
  1. csak a fa struktúráját tároljuk el a fa táblánkban és a hozzá kapcsolódó adatokat külön táblá(k)ban tároljuk
  2. az adatokat és a fastruktúrát egy azon táblában tároljuk

Az első megoldás előnye, hogy az fa egyes elemi, szintjei tárolhatnak különböző jellegű adatokat, míg a második megoldásban az egyes elemek mindig ugyanolyan típusú elemeket tárolnak.
Persze itt is léteznek kerülőutak (ahogy adatbázis kezelésben általában), de ezek kifejtése nem témája ezen cikknek.

Függőségi modell

Első megoldásként az egyszerű és elegánsnak tűnő függőségi modellt fogom bemutatni. Azért elegáns, mert maga az eltárolás elég egyszerű, és egyetlen függvényre van szükség a fa lekérdezéséhez.

A fenti példához az adattárolás második módszerét fogjuk használni a szemléletesség kedvéért.
+-------------+--------------+
| szulo       | felirat      |
+-------------+--------------+
|             | Programozás  |
| Programozás | PHP          |
| PHP         | Stringkezelés|
| PHP         | PEAR         |
| PEAR        | Mail         |
| PEAR        | HttpClient   |
| Programozás | HTML         |
| HTML        | CSS          |
| CSS         | kiválasztók  |
| HTML        | XHTML        |
+-------------+--------------+

A fa lekérdezése

Most hogy már megvan az adattáblánk, már csak meg kell jeleníteni azt valahogy. Kiindulásként a gyökér elemtől indulunk, ami az az elem, amelyiknek ugye nincs szülője (példánkban ez a "Programozás" elem).

<?php
// $szulo a szülőeleme a gyereknek amit látni szeretnénk
// $szint növekszik, ahogy mélyebbre megyünk a fában
// ezt használjuk hogy szépen beljebb kerüljenek a fa elemi
function displayChildren($szulo, $szint) {
   // visszakapjuk a $szulo összes gyerekét
   $result = mysql_query('SELECT felirat FROM tree '.
                          'WHERE szulo="'.$szulo.'";');

   // minden gyermeket megjelenítünk
   while ($row = mysql_fetch_array($result)) {
       // beljebb toljuk és megjelenítjük a gyerek feliratát
       echo str_repeat('  ',$szint).$row['title']."\n";

       // újból meghívjuk a függvényt hogy megjelenítsük a gyerek gyerekeit
       displayChildren($row['title'], $szint+1);
   }
}
?>
Mint láttuk ez egy rekurzív függvény ami a következőképpen működik:
  1. Lekérdezi az elem gyerekeit.
  2. Megjeleníti az elem gyerekét (megfelelően beljebb tolva).
  3. Innen az 1. ponttal folytatja, egészen addig, amíg vannak az elemnek gyerekei, egyébként veszi a következő elemet, ami egy szinten van ezzel.

Hogy az egész fát megmutassuk, üres stringet kell használni a szülőhöz($szulo='') és $szint=0-t a mélységhez.
Meghívva tehát a függvényt: displayChildren('', 0); a következő kimenetet kapjuk:
Programozás
   PHP
      Stringkezelés
      PEAR
         Mail
     HttpClient
   HTML
      CSS
         kiválasztók
      XHTML

Ha egy konkrét elem alá tartozó elemeket akarjuk lekérdezni (példának kedvéért legyen a "PHP"), akkor a függvény meghívása a következőre módosul:
displayChildren('PHP', 0);

Út egy ághoz

Hogy eljussunk egy konkrét ághoz a fában, egy szintén rekurzív függvényt kell használnunk, ami nagyban hasonlít az előzőhöz.
  1. Lekérdezi az elem szülőjét.
  2. Hozzáadja az elem szülőjét az elérési út elejéhez.
  3. Ha ez nem a gyökér elem, akkor folytatja az 1-es lépéssel.
  4. Visszaadja az elérési utat.

<?php
// $node az ág neve, aminek le akarjuk kérdezni az elérését a fában
function getPath($node) {

   // megkeressük az ág szülőjét a fában
   $result = mysql_query('SELECT szulo FROM tree '.
                          'WHERE felirat="'.$node.'";');
   $row = mysql_fetch_array($result);

   // elmentjük az elérési utat egy tömbben
   $path = array();

   // csak akkor folytatjuk ha a $node ág nem a gyökér
   // (annak ugyanis nincsen szülője)
   if ($row['szulo']!='') {
       // az utolsó eleme az elérési útnak a szülő eleme a $node ágnak
       $path[] = $row['szulo'];

       // hozzá kell adni a szülő elemet az elérési úthoz
       $path = array_merge(getPath($row['szulo']), $path);
   }

   // visszaadjuk az elérési utat
   return $path;
}
?>
Maga a függvény egy tömböt fog visszaadni, ami a felirat-okat a gyökértől induló sorrendben fogja tartalmazni.
Használata egyszerű: megadjuk a kívánt felirat nevét, és visszakapjuk az elérési útját egy tömbben. Például:

print_r(getPath('PEAR'));
Visszaadja:
Array
(
   [0] => Programozás
   [1] => PHP
   [2] => PEAR
)

Összefoglalás

Mint láttuk ezek az függvények eléggé egyszerűen használhatók, csak sajnos rekurzívak. Ez bonyolult faszerkezetnél meglassítja az eredmény kijelzését, ugyanis minden egyes elemnél egy új SQL lekérdezés történik (képzeljük el például, hogy egy több ezer tételes kategóriák szerint strukturált könyvtári adatbázisról van szó). Ilyen esetekre sajnos nem elég hatékony, ezért a következő cikkemben bemutatok egy sokkal hatékonyabb megoldást ezen problémák leküzdésére. Illetve annyit szeretnék még megjegyezni, hogy vannak olyan adatbázis kezelők, melyek támogatják a hierarchikus adatlekérdezéseket, és a fent taglalt adatbázis struktúra esetén is lehetőségünk van a teljes fa, vagy csak egy részének lekérdezésére egyetlen query-vel. Például Oracle esetén rendelkezésünkre áll a CONNECT BY szerkezet.
 
Poetro arcképe
Poetro
1998 óta foglalkozik webfejlesztéssel, amikor is a HTML és a JavaScript világa elvarázsolta. Azóta jópár évet dolgozott reklámügynökségeknél, és nemzetközi hírportálok fejlesztésével. Legfőképpen Drupal fejlesztéssel, site buildinggel és JavaScripttel, azon belül is jQuery-vel és Node.js-sel foglalkozik.
1

A téma érdekes

PiG · 2004. Dec. 15. (Sze), 08.14
A téma érdekes, bár lehet, hogy a rekurzív megoldást csak utalás szinten kellett volna tárgyalni, pont a cikkben is említett hátrányai miatt. Már várom a következő részt, bár gyanítom mi lesz benne :-)
Egyébként szerencsésebb lenne a címben a "struktúrált"-at "hierarchikus"-ra változtatni, az adatbázisban ugyanis általában pont struktúrált adatokat tárolunk, ami nem feltétlenül jelenti, hogy azok vaamilyen hierarchiát alkotnak.
P][G
2

Cím változott

Hojtsy Gábor · 2004. Dec. 15. (Sze), 09.50
Teljesen igazad van, a címet megváltoztattam.
3

Köszi

Poetro · 2004. Dec. 15. (Sze), 09.53
Épp én is akartam szólni, hogy PiGnek teljesen igaza van.
--------
Poetro
4

Gagyi

sajt · 2004. Dec. 15. (Sze), 12.05
Hát ez a cikk elég gagyi, de annak, aki nem tudja hogyan kell fa szerkezetet kezelni, annak jo. Azt kerdeznem meg, hogy miert jo az, hogy névvel hivatkozunk a szulore? Miért nem egy id-val? Egyebkent az ilyen fa szerkezetet gyorsabb egyben lekerni, es utana tömbként kezelni.
5

Re: Gagyi

Poetro · 2004. Dec. 15. (Sze), 12.26
Ez a cikk éppen a kezdőknek készül, hogy tudjanak hasonló tartalmakat kezelni.
Szerencsére a kezdők is elég gyakran látogatják az oldalt és nekik mindenképpen segítségként szolgál.
A cikk következő részében már egy jóval komolyabb dologról lesz szó, ami már remélem elnyeri a tetszésedet.
--------
Poetro
6

Visszavonom

sajt · 2004. Dec. 15. (Sze), 12.54
Nem gagyi. :) Csak nem erre szamitottam.
7

tobb reszes cikkek es menu pelda

Jano · 2004. Dec. 15. (Sze), 13.10
Mivel a cikkben volt rola szo, hogy lesz folytatas igy nem sok ertelme van most kiegesziteseket tenni, hiszen lehet/valoszinu pont azokat irod le.

A javaslatom annyi lenne, hogy a tobb reszes cikkek cimeben legyen jelolve, hogy ez csak az elso resz. Vagy peldaul bevezeto, alapok, kezdoknek stb. Igy mindenki tudja mire szamithat.

Ez a cikk kicsit karcsu az eddigiekhez kepest, de mindenkeppen hasznos kezdoknek! Viszont talan eppen a kezdoknek van szukseguk tenyleg preciz mintakra. Lasd elottem az ID-s hozzaszolast. Lehetett volna picit reszletezni jobban az adatbazis szerkezetet.

A forum pelda helyett, vagy mellett lehetne egy tobb szintes menu, UL listas kiirasara pelda. Persze ez mar nem nagy lepes innen megvalositani, de abban az esetben egy rogton felhasznalhato kodreszlet lenne. Hiszen egy UL-s listat CSS-sel formazhatunk utana anelkul, hogy a PHP-hoz hozzákéne nyulnunk. (Es ugye van egy apro buktato is az egymasba agyazott listaknal az UL-LI sorrendet illetoen: a PHP-s kiirasnal nem szabad addig lezarni az adott LI-t mig a gyerek listat ki nem irtuk.)
8

Köszönöm a kritikát

Poetro · 2004. Dec. 15. (Sze), 13.54
Ez volt az első ilyen cikkem, és sajna ebben még elég kezdő vagyok. Legközelebb (ahogy már a folytatásban is) ügyelni fogok arra, hogy out-of-the-box (egyből használható) példát adjak, és az adatbázisos részleteket is jobban kifejtsem.
--------
Poetro
41

Köszönöm

hoczi · 2006. Dec. 30. (Szo), 21.58
Én egy igazi kezdő vagyok adatbázis témában. Nekem nagyon sokat segítettél, köszönöm. Fogalmam nem volt hogy hogy álljak hozzá hasonló dolgokhoz, mostmár van. béke:hocz
9

ha...

zedorg · 2004. Dec. 16. (Cs), 04.40
Ha ez a cikk fokent a kezdoknek szol, akkor nem irunk ilyen pelda kodot, hogy:

<?
$result = mysql_query('SELECT felirat FROM tree '.
                          'WHERE szulo="'.$szulo.'";');
// minden gyermeket megjelenítünk
while ($row = mysql_fetch_array($result))  {
?>
0 hibakezeles, es ez igaz a tobbi par peldara is. A kezdok 1ik ismerve, hogy fogalmuk sincs mi az, hogy hibakezeles, es csodalkoznak, hogy warningol ossze vissza a kodjuk, mi meg csodalkozunk azon, hogy tele a net php warning-os oldalakkal? Aki cikkbe peldat ir, az szerintem irja meg ugy, hogy az publikalni lehessen. /*vagy ez ilyen kezdok a kezdoknek cikk?:))*/
10

Na ne már

sajt · 2004. Dec. 16. (Cs), 11.46
Na, ne izélgessük annyira a cikk íróját. Ezek nem csak az ő hibái, hanem a szerkesztőké is. Én azért már várom a második részt, mert azt hiszem tudom mi lesz benne, és az bizony érdekes lesz...
11

Didaktikai szempontok

pp · 2004. Dec. 16. (Cs), 13.54
Vannak olyan iskolak, es tanarok, akik azt mondjak, hogy warningoljon csak neki, hisz abbol tanulja meg, hogy itt bizony hibat kell kezelni, a cikk ugyanis nem errol szol. (megemliteni azonben meg kellett volna, ebben igazad lehet.)

Volt egy ismerosom akit kiskoraban nagyon feltettek a szulei ezert mindig elkaptak, ha el akart esni. Na olyan szep betonfejeseket ritkan latsz amiket a srac produkalt. Elobb suhant at az agyan az aszfalt mint a gondolat, hogy feltegye a kezet.

Persze egy jol megirt cikkel engem is meg lehet gyozni, es ennek meg a weblabor szerkesztok is orulnenek;) (tudod az ARC plakatrol a csajnak is ezt mondtak, aki a felso legutjabol probalta meg eltavolitani azt a furcsa allagu szerves anyagot.;))

pp
15

Teljesen egyetertek a tulzott

zedorg · 2004. Dec. 17. (P), 17.15
Teljesen egyetertek a tulzott dologgal, de itt nem lenne az:) Nem lovagolni akarok, de az alap szerintem, hogy ha van result, akkor megyek vegig rajta, vagy legalabb oda szurok 1 rohadt @-ot, szal nem full hibaellenorzesre, csak 1-2 dolog ami alap kellene legyen, amikor peldat ir az ember akkor is... /*lehet csak a tragikus hazai helyzet ami a "kezdoket" illet, mondatja ezt velem;) */
16

hat akkor lovagoljunk, ha mar

pp · 2004. Dec. 17. (P), 19.12
hat akkor lovagoljunk, ha mar nem akarsz ;))

1. @ a hibajelzes elnyomasara jo semmi masra -> egy kezdonek inkabb karos, mert nem fogja tudni azt, hogy miert nem fut le a ciklus.

2. Alapvetoen a $szulo valtozot kene ellenorizni, nem az sql lekerdezes eredmenyet. Tehat a cikk iroja nyugodtan mondhatja, hogy figyeljen erre az, aki a fuggvenyt hasznalja. (persze mondhatja idegesen is;))

3. A result hianyabol fakado hibauzenetek tipikusan olyanok, hogy nincs tabla, mezo, hibas az sql lekerdezes stb, szoval olyanok amik csak a fejlesztes soran jonnek elo (-> ergo latni kell oket.) Addig kell maszirozni a dolgot, amig el nem tunnek ezek a hibak, tehat addig amig "nem lehet hibas a lekerdezes" allapotot el nem erjuk.

4. A sok helyen latott "hibakezeles":
$result = mysql_query('SELECT felirat FROM tree '.
                          'WHERE szulo="'.$szulo.'";') or die('hiba a lekerdezes soran');

szerintem dilettans megoldas, megis ezt tanitjak a kezdoknek, ugye nem erre gondoltal;))

5. az, hogy Pistike nulla tudassal bevallal egy olyan munkat, amely kepessegeit joval meghaladja, es eloallit "valamit ami mukodik" nem elitelendo. (vagy itt csak olyanok vannak, akik sose vallaltak be semmi olyat amihez nem ertettek szaz szazalekossan?)

6. az, hogy sok esetben kizarolag az ar az egyetlen szempont amikor webmestert valasztanak a vevok, se nem a cikk irojanak, se nem a "kezdoknek" (avagy kontaroknak) a hibaja.

<lorolle />

Tenyleg nem lehetne egysegesiteni a neveket? Tehat vagy "szulo" helyett "parent", vagy a "DisplayChildren" helyett valami magyar, mert ez a kavar tenyleg zavaro.

pp
17

Egy sor...

sajt · 2004. Dec. 18. (Szo), 10.18
Vegul is itt egy soron lovagolunk. Az elsőn valahogy így kellene:

<?php
 if ($row = mysql_fetch_array($result)) {
   //fuggveny torzse
   return $path;
 } else {
   return false; //vagy amit akarsz
 }
?>
Nem?

Persze még nagyon sok mindenbe bele lehetne kötni, de minek. A cikk aról szól, hogy hogyan kell ilyen fákat kezelni elméletben.

De mondom, várjátok meg a cikk 2. részét, attól majd mindenki dob egy hátast.
18

azabaj

pp · 2004. Dec. 18. (Szo), 19.12
Te most elrontottad a fuggvenyt ;)
A fuggveny neve DisplayChildren (mutasd a kölyköket;)), es tokeletesen mukodik, mert ha nincs egy talalat se, akkor nem ir ki semmit sem.

En ugyan azt mondom amit Te, hogy a cikk nem arrol szol, hogy hogyan keszitsuk fel minden eshetosegre a fuggvenyeinket, hanem a hierarchikus adatkezelesrol ;)

Reszemrol erre reagaltam:
"Ha ez a cikk fokent a kezdoknek szol, akkor nem irunk ilyen pelda kodot, hogy"

A programozas nem ping-pong, ahhol egy rosszul rogzult mozdulatot evekik tart kijavitani. Amikor programozik az ember, es talal valahogy egy jobb megoldast/modszert, akkor automatikusan azt kezdi el hasznalni, es nem kell leszoknia a regirol, mert azt kb 2-3 het alatt el is felejti;))

pp
12

Hierarchikus adatkezelés SQL-lel PHP-ben

adamkof · 2004. Dec. 16. (Cs), 17.33
Nekem tetszik a cikk. Én nem hiányolom hibakezelést, a szükséges cifraságokat, végül is nem egy készterméket mutatba a cikk, nem egy mindenki által használható osztályt készít, hanem csak az elvet lehet áttekinteni, ahhoz meg ez elég. Ami engem érdekelne az a különböző faszerkezetek. Pl. másról van szó ha a fa levelein csak olyan értékek lehetnek amelyek egy törzsből jönnek és előbb a törzset kell bővíteni, ill. ha törlök a fából akkor mi legyen a törzsbeli elemmel stb. Érdekelne a fa átértékelése, egy levél máshova helyezése és így tovább. Persze nyilván egy cikk keretei végesek, de mégis :-)

hali
13

Hogy is van ez.

sajt · 2004. Dec. 17. (P), 14.08
Minden erteknek kell lennie egy szulojenek, kiveve az un. gyoker elemnek, aminek nincs szuleje.

Levél, vagy ág áthelyezésekor elég csak a szülőt módosítani.

Törlésnél meg kell vizsgálni, hogy az adott elemnek vannak-e gyerekei. ha vannak, akkor szolni kell, hogy nana.
14

Nagyjából

dtaylor · 2004. Dec. 17. (P), 16.21
igy is van. + meg meg kell nezni, ne a sajat al fája ala akarjad csatolni...

--
[ Dönci ]
19

Igen. Pontosan azok az egysze

adamkof · 2004. Dec. 18. (Szo), 21.23
Igen. Pontosan azok az egyszerü, de lényeges mondatokat kellenek a cikkbe amit sajt is, és dtaylor(dönci) is írtak. Ezek tartoznak a faszerkezet kezeléséhez. Végül is nem olyan bonyolult egy fát kezelni :-). Ezek a mondatok és a hozzátartozó kód részletek kellenek, ha már kezdőkről beszélünk :-). A hibakezelést persze meg kell említeni, de csak jelzés színten.

hali
20

varjuk ki 2. reszt

Jano · 2004. Dec. 18. (Szo), 22.47
Sracok, varjuk ki masodik reszt! Cikket irni, nem olyan egyszeru. Egyszerre torekedni arra, hogy jo peldat mutass, es hogy a sok mellekes, szukseges dolog ne vonja el a figyelmet a lenyegi mondanivalorol.
Remelem a szerzo epito jellegu kritikanak fogja fel az itt elhangzottakat es nem ment el a kedve a cikk irastol :)
En csak biztatni szeretnem, hogy hajra!
21

nem ment el a kedvem

Poetro · 2004. Dec. 19. (V), 15.02
Van egy jó hírem! :)
Nem ment el a kedvem a cikk folytatásától, inkább látom hogy sokakat érdekel a problémakör, sőt még a php levlistára is valahogy beszivárgott ez a cikk, tőlem függetlenül. Szóval mivel van rá igény, és én is fejlődni akarok cikkírás tekintetében is, remélhetőleg még Karácsony előtt, ha nem, akkor a két ünnep között mindenképpen elkészítem a cikk második felét.
Janonak igaza van. Nem egyszerű cikket írni, mindenre oda kell figyelni, és úgy kell leírni, ami az ember fejében van, hogy azok is megértsék, akik aktuálisan nem foglalkoznak a problémakörrel.
Magát a kódot és az elképzelést is pofozgatni kell, és legközelebb olyan cikkel akarok előállni, amit tényleg többször átgondoltam, átolvastam, hogy minden esetleges hibát kigyomláltam már belőle. Sajna ez így sikerült, ritkán jön össze elsőre próbálkozásra tökéletes eredmény.
Ha más is kedvet érez ezek után, hogy cikket írjon, szívesen segítek is neki, mert kezdem átlátni a buktatóak, szóval senki se hátráljon meg.
Főleg mivel nem csak php és SQL témakörben szeretnék majd cikket írni, hanem majd Flash kapcsán is, elvégre kezd egyre jobban beszűrődni a dinamikus tartalmak közé a Flash, egyszerűségével, szépségével és hordozhatóságával.
--------
Poetro
22

További anyagok

Nagy Péter · 2004. Dec. 28. (K), 22.23
Javasolnék a téma iránt érdeklődőknek egy nem túl új, ám (szerintem) jó cikket, angolul:
Storing Hierarchical Data in a Database

Én a 2. oldalon részletezett mechanizmust érdekesnek találtam, bár lehet, hogy a dolog csak nekem volt akkor új.

NP
30

Ejnye-bejnye

Anonymous · 2005. Aug. 25. (Cs), 12.59
Tekintve, hogy ez a sitepoint-os cikk, az alapja a fentinek (ha nem is tükörfordítás, de majdnem) ezért talán meg kellett volna jelölni forrásként valahol a végén.
23

dirListázó

toxin · 2005. Jan. 7. (P), 14.38
csak érdekességképpen még anno írtam egy fájlrendszer2fastruktúra2PEAR:treeToMenu konvertert ami pont ide kapcsólodik
van benne egy alapkonténer abba kerülnek a könyvtárak egymáshoz a fastruktúrának megfelelően parentId-vel kapcsolja őket (szintén rekurzió) a végén pedig meghatja a PEAR-es treeToMenu objektumot (a megfelelő belső konverzió után clsContDir:treeToMenu)
http://projektm.uw.hu/tutorial/dirTree.ZIP (paraméterezni az elejét és a végét kell)
http://pear.php.net/package/HTML_TreeMenu

a későbiekben aztán lett ennek folytatása ami egy tetszőleges könyvtárstuktúrát a megfelelő metainfo-kal elhelyez 2 táblába de az már egy teljes cikk lenne :)
24

úgy egyáltalán az egész értelme

Anonymous · 2005. Jan. 15. (Szo), 18.23
mi az értelme? láttunk egy adatolvasási folyamatot.

1. ) Hasznos-e?
A menü vagy fa szerkesztésére külön felület vagy interface kell, ha adatbázisba tesszük.
Ennél jobbnak és közvetlenebbül felhasználhatónak tartom az xml-t. (Adatbázisba begyurmászását, plusz lépésnek) egy menü esetén. Ami többnyire design elem is. XSLT remekül alkalmazható.
2.)
van-e értelme állandóan fákat lekérdeznünk és tárolgatnunk.
Ha jól emlékszem nem jó tervezési elv egy táblának saját magára tartalmaznia mutatókat. ( mert be kell járnunk az egészet. többnyire rekurzívan. és erre nem csak az igen fejletlen MySQL esetében nem létezik intelligens megoldás.)
3.)
még a végén ezek alapján valami hatalmas fát rakok össze. ami relációs adatbázisnál kellemetlenül érint. Tekintve, hogy pont a sokszoros függést próbálom elkerülni a normalizálás során. Ezt a lépést technológiai visszafejlődésnek érzem.
A menüt állandóan így kirakni szerintem kicsit gáz.
25

felületről beszélsz

Hojtsy Gábor · 2005. Jan. 15. (Szo), 19.02
Én úgy látom, hogy felületről beszélsz, egy XML-t is lehet ilyen adatbázis szerkezethez mappelni, és ebből is lehet XML-t generálni. Nem dinamikus tartalmat természetesen nem érdemes mindig újra legenerálni a forrás adatokból, ha lehet kesselni kell.
26

pontosan ezt mondtam. a krit

Anonymous · 2005. Jan. 15. (Szo), 23.02
pontosan ezt mondtam.
a kritikám negatív a cikkel kapcsolatban.
27

Alapok

Bártházi András · 2005. Jan. 16. (V), 11.05
Ebben a cikkben az alapokról volt szó, s nem lehetett a célja, hogy az összes kapcsolódó lehetőséget bemutassa. Tehát valóban kijelenthető, hogy hiányzik a cikkből ezeknek a témákban a tárgyalása, de ez negatív kritikaként nem fogalmazható meg a cikkel szemben, mivel nem volt célja. Szerintem.

-boogie-
37

mi az értelme... az XML-es megoldásnak???

Anonymous · 2005. Dec. 19. (H), 11.59
Lehet h én vagyok a tudatlan (sőt biztos), de engem még egy cikk sem tudott meggyőzni, h miért használjak XML-t adatbázis helyett... Mert az XML-nek azon kívül, h hordoz6ó semmi előnyét nem érzem, hiszen az átlag felhazsnáló nem tudja SZERKESZTENI. Persze a megjelenítéshez érdekes lehet, de mit nyerünk vele, h egy újabb szabványt kiszolgálunk tudásunkkal???

Írtad:
"A menü vagy fa szerkesztésére külön felület vagy interface kell, ha adatbázisba tesszük. Ennél jobbnak és közvetlenebbül felhasználhatónak tartom az xml-t."

Kérdésem:
Milyen közvetlen interfésszel (ami mindenki gépén fennt van, nem arra gondolok pl. h "töltsön le és tanuljon meg egy XML szerkesztőt"-re gondolok; mert a brózerekben (IE) csak "nyitogatni-csukogatni" lehet a megjelenített XML-t) tudja az átlag felhasználó SZERKESZTENI pl egy XML-ben tárolt fa-szerkezetű adatbázist (fa-szerkezet pl: fotógaléria kategorizálásához használom, amit egy adminon szerkeszt az "átlag felhasználó").

(Mindenhol ez az XML "majmolást" látom(ez durván hangzik, de mint elmélet), Valaki mondja meg h miért jó minden nap új szabványt alkotni valamire, ami már megoldott? Ez is a "platformharc" része??? Mostanában ezen gondolkodom. Mert ha tényleg jó dolog, akkor én is szeretném használni.)

Pistván - karist##kukac##citromail.hu
38

közvetlen interfész

Hojtsy Gábor · 2005. Dec. 19. (H), 12.33
Miért, te milyen közvetlen interfészt tudsz mutatni, amely minden gépen rajta van, és adatbázisban (nem XML-ben) megadott faszerkezeteket lehet vele szerkeszteni?
39

Nem tudok ilyen interfészt

Anonymous · 2005. Dec. 20. (K), 10.26
Sajnos nem tudok ilyen interfészt mutatni.
De pont ezért kételkedem az XML-ben, hogy az miért jobb, mert ahoz sincs semmi felület, de legaláb bonylítja az életet. Vagy rosszul látom? Nos erre kéne nekem okos válasz.

Mert ha már XML, akkor miért nem lehetett már egyből a böngészőkbe egy "alap" interfészt integrálni(ami nem csak csiki-csuki módon jeleníti meg szerencsétlen XML-t), hamár úgyis sok helyen használják és szabványosított dologról van szó, hogy tényleg használ6ó legyen.

Mert csak hallom hogy vagány dolog, de miért???? Egy újabb szabvány??? Elegem kezd lenni abból, h minden nap újabb szabványt kéne megtanulni, ami végtére nem is segít, hanem csak nő a "bürokrácia".

KarIst.
40

faszerkezet

Hojtsy Gábor · 2005. Dec. 25. (V), 12.41
Az XML sokkal jobban kifejezi a faszerkezetet, az az alapja. Az adatbázisra rá kell ezt erőltetni, illetve pontosabban fogalmazva megvannak a szokásos tervezési minták, amiket a cikk is leír, ezeket használják, de erre egyedi szerkesztői felületet kell készítened, mondjuk egyedi export formátummal. Márpedig a faszerkezet, akár kategóriákról, akár menükről vagy webhely térképről van szó, nagyon gyakori.

Nem kell megtanulni az XML-t, ha nem akarod használni, és nem gondolod, hogy jobb. Az, hogy adott feladatra mi az alkalmasabb, te döntheted el, ha más körülmények nem befolyásolnak. De ez a téma túlmutat a hierarchikus adatkezelés keretein, egy másik fórum témában kellene megvitatni.
28

Kapcsolódó dokumentum

Török Gábor · 2005. Ápr. 10. (V), 17.50
29

re: Kapcsolódó dokumentum

Poetro · 2005. Ápr. 11. (H), 16.30
Köszönöm a hasznos olvasnivalót az elmélet mélyebb elsajátítása végett.
--------
Poetro
31

POETRO? != LOPÁS

Anonymous · 2005. Aug. 25. (Cs), 13.51
Ez így a sitepoint-os cikk 1-1ben való ellopása.

http://www.sitepoint.com/article/hierarchical-data-database
32

Hm.

Granc Róbert · 2005. Aug. 26. (P), 11.43
Köszönjük kedves névtelen hozzászólónknak hogy felhívta a figyelmet a rendkívüli hasonlóságra a Sitepoint és Poetro cikke között. Hozzászólónk szóhasználatát kissé erősnek tartjuk, és szerencsére így vélekedtek a Sitepoint szerkesztői is, így - szerencsére - megkaptuk utólagos jóváhagyásukat a kérdéses cikkük felhasználásához.

Minden olvasónktól elnézést kérünk a történtekért! Igyekszünk mindent megtenni annak érdekében hogy a jövőben hasonló eset ne fordulhasson elő.
33

Korrekt

Anonymous · 2005. Aug. 26. (P), 20.31
Korrekt.
34

<Nincs cím>

Anonymous · 2005. Szep. 19. (H), 19.36
Ráadásul a cikk második része is "másolt".
Az ilyet nem kellene megengedni.
35

honnan?

Hojtsy Gábor · 2005. Szep. 19. (H), 21.06
1. Ez a hozzászólás hogyan kapcsolódik a cikk első részéhez?
2. Honnan másolta a szerző a második részt szerinted?
36

Nincs

Bártházi András · 2005. Szep. 19. (H), 21.13
Nincs is megengedve. Ennél a cikksorozatnál utólag derült ki, hogy túlzottan épít egy másik cikkre, a felhasználásra azonban utólag engedélyt kaptunk (ahogy az a hozzászólásokból látszik is). A jövőben megpróbálunk egy kicsit jobban figyelni majd erre. Ha bármilyen olyan dolgot veszel észre, mely jogtalanságra, vagy etikátlanságra utal, akkor kérlek kicsit részletesebben fejtsed ki a dolgot / vedd fel velünk a kapcsolatot.

-boogie-
42

Hierarchia - Sorrend - NemRekurzív megvalósítás

RajcsanyiZ · 2010. Jún. 21. (H), 21.08
Bizonyára az alábbi kód egyszerűsíthető, de amennyiben nem rekurzívan arra vagyunk kiváncsiak, hogy egy lista elemeit, milyen sorrendbe kell kiiratni, akkor az alábbi program egy megoldás. Életszerűen a programot úgy érdemes kibővíteni, amikor a hierarchia módosul, akkor az adatbázisban a mélységet és a sorrendet a kis szkriptel beállíthassuk.

  $arrOrig = array(1=>'', 2=>'', 3=>1, 4=>1, 5=>4, 6=>2, 7=>6, 8=>1, 9=>8, 10=>2, 11=>1,12=>8);
  
  echo "<h1>Gyerek-Szülő tárolási forma: </h1>";
  echo "<pre>";
  print_r($arrOrig);
  echo "</pre>";
  
  // gyerek elemek meghatározása   
  $children = array();
  foreach ($arrOrig as $id=>$parent) $children[$id]=array();
  foreach ($arrOrig as $id=>$parent) {
    if ($parent != '') {
      $children[$parent][] = $id;
    }
  }    
  
  // szülők gyermekeinek a számának a meghatározása     
  foreach ($arrOrig as $id=>$parent) {
    $childnum[$id] = count($children[$id]);
  }
  
  // szülők meghatározása  
  foreach ($arrOrig as $id=>$parent) $parents[$id]=array();
  foreach($arrOrig as $id=>$parent) {
    if ($arrOrig)
    if ($parent != '') {
      $parents[$id] = array_merge(array($parent), $parents[$parent]);
    }
  }   
  
  // elem mélységének és maximális mélység meghatározása
  $level_max = 0;          
  foreach ($arrOrig as $id=>$parent) {
    $levels[$id] = count($parents[$id]);
    if ($levels[$id] > $level_max) $level_max=$levels[$id];
  }
  
  $items = array();
  foreach ($arrOrig as $id=>$parent) {    
    $items[$id] = array('id'=>$id, 
                        'parent'=>$parent,
                        'level'=>$levels[$id]);    
  }
  
  // hierarchia szerinti sorba rendezés
  
  // szülő elem a feltöltés állapotában mennyi gyerek elemet tartalmaz
  $order = array();
  foreach ($arrOrig as $id=>$parent) $addition[$id]=0;
  $i = 0;   
      
  $items2 = array();
  for ($level = 0; $level <= $level_max; $level++) {    
    foreach ($items as $item) {
      if ($item['level'] == $level) {
        $i++;        
        $id = $item['id'];
        // ha ős elemről van szó
        if ($level == 0) {            
          // egyszerű beszúrás                
          $order[$i] = $id;         
        } else { // az elemnek van szülője
          $parent = $arrOrig[$id];
          // elem szülőjének a sorszámának a megkeresése
          for ($parent_place=1; $parent_place<$i; $parent_place++) {
            if ($order[$parent_place] == $parent) {
              break;
            }
          }
          $ins_item_num = $parent_place+$addition[$parent];                    
          
          // régi elemek léptetése egyel előre és az új elem beszúrása a megfelelő helyre         
          for ($a=$i; $a>$ins_item_num; $a--) {          
            $order[$a+1] = $order[$a];                        
          }          
          $order[$ins_item_num+1] = $id;                           
                                              
          $addition[$parent]++;                            
                  
        }                    
      }
    }    
  }
  
  echo "<h1>Sorrendben: </h1>";    
  echo "<pre>";
  print_r($order);
  echo "</pre>";